Commit Graph

5430 Commits

Author SHA1 Message Date
copilotkit-qa-bot[bot] 29cf68640a fix(docs): preserve complete production code blocks 2026-09-09 10:52:49 -07:00
copilotkit-qa-bot[bot] f712369889 Merge remote-tracking branch 'origin/main' into codex/fac-197-state-snapshot-docs 2026-09-09 10:01:14 -07:00
copilotkit-qa-bot[bot] be5315556c docs(crewai): verify AG-UI endpoint before cloud setup 2026-09-09 09:24:28 -07:00
Mike Ryan b17e238aa3 docs: show the component tool imports for the built-in agent (#6959)
The Components as Tools page shows a `useComponent` call without its
import. An onboarding run using the built-in agent had to inspect
installed type declarations to find it (friction report R16).

Show the `@copilotkit/react-core/v2` hook import and Zod import directly
on the shared page, including the built-in agent route.

Validation:
- `npm run typecheck` and `npm run build` passed in
`showcase/shell-docs`.
- `npm run test -- src/lib/__tests__/docs-render.test.ts
src/lib/__tests__/setup-concept.test.ts --maxWorkers=1` — 39 tests
passed.
- Browser smoke against the production build verified the visible
imports at `/built-in-agent/generative-ui/tool-based` and the same
import in its `.md` response.
- `pnpm exec oxlint showcase/shell-docs` — zero errors, existing
warnings remain; commit hooks and `git diff --check` passed.
- The broad docs test suite hit unrelated navigation/search UI failures
and excessive worker memory use; it was stopped. No application behavior
changed in this PR.


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

## Summary by CodeRabbit

* **Documentation**
* Added guidance for importing `useComponent` and Zod when registering
tools for tool-based Generative UI.
* Clarified that the same approach applies to the built-in agent, which
does not require backend tool registration.
  * Included a TypeScript example showing the required imports.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 20:22:15 -07:00
Benjamin Taylor 274983d4f8 fix(docs): make the redirect suffix-aware and repair dead links the regeneration surfaced
Self-review follow-ups on the reference-docs regeneration.

The LangGraphAgent redirect only covered the bare path. A raw Markdown request
reaches redirects before the .md/.mdx rewrite, so a request for
/reference/v1/sdk/python/LangGraphAgent.md would have 404'd for the LLM routes.
Use permanentRedirectsWithSuffixes, which is what the rest of the redirect
table does.

Refreshing the pages also republishes their JSDoc links, and three of those
pointed at pages that do not exist. They were invisible while the pages were
frozen; regenerating makes them live 404s, so fix them at the source:

- use-coagent-state-render.ts linked to /coagents/videos/perplexity-clone, a
  legacy URL with no content, no redirect and no rewrite. Point at
  /generative-ui/state-rendering, the canonical guide the published page
  already named.
- copilotkit-props.tsx linked to
  /coagents/shared/guides/langgraph-platform-authentication, which likewise
  does not exist. Point at /auth, which is how the rest of the docs link to
  that guide.
- use-copilot-chat.ts was flipped to
  /reference/v2/hooks/useCopilotChatHeadless_c by the URL canonicalization in
  33f669ba7b, but there is no v2 page of that name — reference/hooks has no
  headless entry. Restore the v1 page, which exists and is what the published
  page links to today. If v1 readers should be pushed to a v2 page instead,
  that page has to be written first.

Every internal link the regeneration newly publishes now resolves to a content
file.

The three package edits are JSDoc comment lines only; no code changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 21:58:48 -05:00
Benjamin Taylor c11329c5dd fix(docs): stop the internal v1 deprecation banner leaking into reference pages
The v1 deprecation notice added in #6582 is a source-file banner for IDEs and
coding agents, including the line "AI CODING AGENTS: Never copy, suggest, or
generate these v1 APIs." It sits in the leading trivia of the first statement
of every public v1 source file, which is the same place the reference-docs
generator reads real JSDoc from, so regenerating embedded it as visible body
text on 20 published pages. That made regeneration unpublishable: no JSDoc
correction to a v1 source could land without also shipping the banner.

Skip the notice wherever the generator enumerates comment ranges, keyed off its
stable opening delimiter.

Also repoint the six SDK reference entries. Their pages moved to
reference/v1/sdk/ in ec239b15f7 and the old copies were deleted in a8d43a9c2e,
but files.ts still wrote to reference/sdk/, so the generator refreshed a
directory the docs site never served while the live pages went stale. Those
pages regain the upstream LangGraphAgent -> LangGraphAGUIAgent rename and the
copilotkit_emit_tool_call tool_call_id parameter. The renamed page replaces the
orphaned LangGraphAgent page, whose source file no longer exists, with a
permanent redirect for the old URL.

Regenerating is now idempotent: a second run leaves the tree clean.

Fixes #6939

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 21:44:18 -05:00
Ben Taylor f7192ee40c docs: persist the reader's code-tab choice, and link out to provider key pages (#6925)
Two independent docs-frontend improvements in `showcase/shell-docs`.
Rebased onto current `main` (the branch was 158 commits behind).

## 1. `<Tabs persist>` now actually persists

101 tab groups in the content tree are authored as `<Tabs groupId="..."
persist>`. The wrapper accepted both props and ignored them — the
comment in `docs-tabs.tsx` said so outright:

> `groupId` and `persist` are accepted and currently ignored

So every page reopened on its own default. A reader working through the
LangGraph guide in TypeScript had to reselect TypeScript on each page.

Fumadocs holds tab selection in local component state and exposes no
persistence hook, so the wrapper takes over the controlled
`value`/`onValueChange` pair and mirrors the pick into `localStorage`
under `shell-docs.tab.<groupId>`.

**Selection precedence**, strongest first:

| # | Source | Where it comes from |
|---|--------|---------------------|
| 1 | `urlDefault` | The framework-route override the page shell derives
from the URL (`TAB_DEFAULTS_BY_SLUG`) |
| 2 | Stored pick | `localStorage`, same `groupId` |
| 3 | `default=` | The author's value in the MDX |
| 4 | First item | Fallback |

The page shell passes its URL-derived value as a **separate `urlDefault`
prop** rather than overwriting `default`. This matters: 45 of the 101
`persist` groups also carry an author `default=`. Collapsing the two
sources into one prop ranks the author's default above storage, which
would leave the stored pick unreachable on almost half of the pages the
feature exists for. `language_langgraph_agent` appears both ways (30
sites with `default="Python"`, 8 without), so the same group would have
behaved inconsistently within one guide.

Two details worth noting for review:

- The stored value is read in an **effect**, not in the initial state,
so server and client render identical markup and hydration stays clean.
- Every `localStorage` read and write is wrapped in `try`/`catch`.
Private mode and quota errors leave the tabs fully working, just without
persistence.

## 2. API-key hints under `.env` snippets

The LangGraph quickstart tells the reader to put `OPENAI_API_KEY` in
`.env` and leaves them to go find the key page. `<ApiKeyHint
provider="openai" />` renders a muted one-line link under the snippet.

The component maps a provider id to a label and URL — `openai`,
`anthropic`, `google`, `langsmith`, `copilotkit`. An unknown id renders
nothing, so a typo degrades to today's behaviour instead of throwing. It
is navigational only: it neither reads nor writes a key. Both `.env`
steps on the LangGraph quickstart use it.

## Removed from this branch

The earlier revision led the LangGraph quickstart with a `<InlineDemo
demo="agentic-chat" />` block under a "See it working" heading. That is
gone, along with the `inline-demo.test.tsx` file that covered it —
`InlineDemo` is pre-existing `main` code this PR no longer touches.

Two tests in `docs-page-view-toc.test.tsx` were also dropped rather than
kept. They were named for this PR's components but did not exercise
them: `docs-page-view-toc.test.tsx` asserts on `DocsPage` props, and the
page body is never rendered. Verified by mutation — deleting
`ApiKeyHint` from the MDX registry left the test titled `renders the
LangGraph quickstart (InlineDemo + ApiKeyHint) without errors`
**passing**. Real coverage lives in `api-key-hint.test.tsx` instead.

## Testing

No CI job runs the `showcase/shell-docs` vitest suite.
`test_unit-showcase.yml` covers only `harness` and `shell-dashboard`;
`showcase_validate.yml` runs vitest only in `showcase/scripts`.
Everything below was therefore run locally.

**Full suite, branch vs. pristine `origin/main` in the same
environment** — `main` carries 6 pre-existing failures here, so the
failure *set* is the comparison, not zero:

```
base   (origin/main)  843 tests, 6 failed
branch (this PR)      858 tests, 6 failed
NEW failures: none
```

The 6 are identical on both sides: `brand-nav` layout cap, 3 ×
`angular-docs-content`, `llm-text` mastra, `ms-agent-python-stable-api`.

**Mutation checks** — every new test was verified to fail when the
mechanism it claims to cover is broken:

| Mutation | Result |
|----------|--------|
| `canPersist = false` (persistence off) |  `persists a groupId pick
and reapplies it on a fresh mount` fails |
| Author `default` outranks storage (the pre-fix precedence) |  `ranks
a stored pick above the author's MDX default` fails |
| `urlDefault` demoted below author `default` |  `ranks a urlDefault
above the author's MDX default` fails |
| `ApiKeyHint` removed from the MDX registry |  `is registered as an
MDX component` fails |
| `href={meta.url}` → `href={undefined}` |  5 of 7 `ApiKeyHint` tests
fail |

**End-to-end render** — `ApiKeyHint` was rendered through the real
`MDXRemote` pipeline (same `remarkGfm` options, nested in
`<Steps>/<Step>` as the quickstart uses it) to confirm the `provider`
prop survives compilation and the anchor reaches the HTML:

```
✓ ApiKeyHint through the real MDX pipeline > survives compilation with its provider prop
  expect(html).toContain("https://platform.openai.com/api-keys")
```

**Typecheck and lint** (`showcase/shell-docs`):

```
$ npx tsc --noEmit      → exit 0
$ npx oxlint .          → Found 28 warnings and 0 errors
$ npx oxfmt --check <touched files>  → All matched files use the correct format
```

The 28 lint warnings are pre-existing. The only two in a file this PR
touches (`mdx-registry.tsx`) are `iframe-missing-sandbox` on
pre-existing `InlineDemo` iframes, untouched here.

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


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

## Summary by CodeRabbit

* **New Features**
* Added inline API key guidance below relevant documentation code
blocks, with links to provider credential pages.
* Added tab selection persistence across documentation pages, with
support for URL and author-defined defaults.
  * Added API key guidance to the LangGraph quickstart.
* **Tests**
* Added coverage for tab persistence, selection precedence, invalid
values, disabled persistence, and API key hint behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 21:12:51 -05:00
Benjamin Taylor 0868314acd test(shell-docs): cover the CTACards page wiring
A self-review of the previous commit found three gaps.

- Nothing tested that the page wires the fixes up. A new test walks the
  rendered `DocsPageView` tree, asserts `blockJS` is off in the page's
  own MDXRemote options, and renders the registered `CTACards` override
  to confirm it prefixes card hrefs with the framework being read.
  Removing either the option or the override fails it.
- The compile test asserted `grid-cols-1`, which the two-column class
  also contains, so the `columns` half of that test proved nothing. It
  now asserts the absence of the `sm:` variant.
- The per-page test guarded the extracted href count but not the title
  count, so a regex that matched no titles would have passed silently.

Also correct the component comment: four content files author the
block, but the pydantic-ai one is shadowed by a sibling leaf file and
renders nowhere.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:41:35 -05:00
Benjamin Taylor d083d8a7a4 fix(shell-docs): let the authored CTACards props reach the component
The component fix alone was inert on the real page. next-mdx-remote 6
defaults `blockJS` to true, which runs a remark plugin that deletes
every JSX attribute whose value is an expression. On the docs route
`<CTACards columns={2} cards={[...]} />` reached the component with no
props at all, so it still rendered an empty grid. The unit tests passed
because they call the component directly and skip the MDX pipeline.

- Turn `blockJS` off for the docs route. Every source there is
  first-party content from `src/content`. `blockDangerousJS` keeps its
  default. The other MDXRemote call sites keep the default too, because
  `ag-ui/introduction.mdx` authors inline `onMouseEnter` handlers that
  the stripping currently keeps out of a server component.
- Resolve each card href against the framework being read. The cards
  render through the registry `Card`, so they never reached the
  href-resolving `Card` override, and a reader on
  `/ms-agent-python/human-in-the-loop` was redirected to the .NET page.
  Content now authors the hrefs root-relative.
- Stack the grid to one column below the `sm` breakpoint. An inline
  `grid-template-columns` cannot be overridden by a class, so the two
  cards stayed 157px wide side by side on a 390px viewport.
- Pass each description through the `Card` `description` prop, the same
  as every other card grid in the docs.
- Match `iconKey` against own properties only.
- Add a test that compiles the four authored blocks through the MDX
  pipeline, which is the check the earlier tests were missing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:41:35 -05:00
Benjamin Taylor 22cc2bf303 fix(shell-docs): render the CTACards a page actually authors
`CTACards` accepted only `children`, but every call site in content
authors `<CTACards columns={n} cards={[...]} />` self-closing. Both
props were dropped, so the grid rendered empty and the pages lost
their links with no error anywhere.

Four human-in-the-loop landing pages are affected: crewai-flows,
mastra, pydantic-ai, and microsoft-agent-framework.

The component now renders each entry through the shared `Card`, honors
`columns` in the grid template, and falls back to wrapping `children`
so legacy `<CTACards>...</CTACards>` authoring keeps working — the same
prop-or-children contract `EcosystemTable` uses in this file.

`iconKey` values on these cards are lucide names, not the framework
keys in `customIcons`, so they get their own lookup. An unregistered
key renders the card without an icon rather than throwing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:41:34 -05:00
Benjamin Taylor a04f0f7640 feat(docs): link out to the provider key page from .env snippets
The LangGraph quickstart tells the reader to put `OPENAI_API_KEY` in
`.env` and leaves them to find the key page themselves. `<ApiKeyHint
provider="openai" />` renders a muted one-line link under the snippet.

The component maps a provider id to a label and a URL, covering openai,
anthropic, google, langsmith and copilotkit. An unknown id renders
nothing, so a typo degrades to the current behaviour instead of
throwing. It is navigational only: it neither reads nor writes a key.

Both `.env` steps on the LangGraph quickstart use it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:41:24 -05:00
Benjamin Taylor 9157f27f9b feat(docs): persist the reader's code-tab choice across pages
`<Tabs groupId="..." persist>` is written on 101 tab groups in the docs
content tree, but the wrapper accepted both props and ignored them: the
comment in docs-tabs.tsx said so outright. Every page therefore reopened
on its own default, so a reader working through the LangGraph guide in
TypeScript had to reselect TypeScript on each page.

Fumadocs holds tab selection in local component state and exposes no
persistence hook, so the wrapper takes over the controlled
`value`/`onValueChange` pair and mirrors the pick into localStorage
under `shell-docs.tab.<groupId>`.

Selection precedence, strongest first:

  1. `urlDefault` — the framework-route override the docs page shell
     derives from the URL via TAB_DEFAULTS_BY_SLUG.
  2. A stored pick for the same `groupId`.
  3. The author's `default=` written in the MDX.
  4. The first item.

The page shell now passes its URL-derived value as a separate
`urlDefault` prop instead of overwriting `default`. Collapsing the two
into one prop would rank the author's default above storage, and 45 of
the 101 `persist` groups carry an author `default=` — the stored pick
would have been unreachable on almost half the pages the feature exists
for.

The stored value is read in an effect rather than in the initial state,
so server and client render the same markup. Reads and writes are
wrapped in try/catch: private-mode and quota errors leave the tabs
working without persistence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:41:24 -05:00
Ben Taylor 862ff3c180 fix(react-core): name the agent on CopilotKitProvider, warn when threads meet single-route (#6892)
Fixes OSS-1133

Rebased onto `main`. The branch was 205 commits behind, and two of its
three changes did not survive contact with current `main`. Both are
corrected here, so this description replaces the original one rather
than adding to it.

## What changed on `main` under this branch

**The single-route warning is gone.** The branch added a `useThreads`
development warning on the premise that "the thread routes live outside
the single-route envelope, so the list stays empty". That premise is no
longer true. `main` now carries thread, memory, and annotation
operations through the single-route endpoint with a `resource/request`
envelope (`fetch-handler.ts:405`), advertises it as
`singleRoute.resourceOperations` (`get-runtime-info.ts:177`), and the
client reads the thread endpoints from there (`agent-registry.ts:1367`).
A current single-route runtime serves threads, so the warning fired on a
working configuration.

Narrowing it does not rescue it either: when the transport is `single`
and the endpoints are still unavailable, the cause is a missing
Intelligence or thread backend, not the transport — the client cannot
tell those apart. The hook already surfaces the knowable fact through
`threadEndpointsError`. The warning, its three tests, and the
`useThreads.mdx` callout are dropped; `use-threads.tsx` and its test
file are now byte-identical to `main`.

**The docs' `useSingleEndpoint` claim is stale.** Both pages said
released versions of `<CopilotKit>` pin the flag to `true`. `dc73af1dc4`
removed that pin and is an ancestor of the `v1.70.2` release, which is
what `npm` serves today. Corrected on both pages.

## What this PR does

### `agentId` on `CopilotKitProvider`

```tsx
<CopilotKitProvider runtimeUrl="/api/copilotkit" agentId="my_agent">
```

`CopilotKitProvider` carries no agent prop at all, so the only way to
name an agent at the provider level is the v1 compatibility component.
The reporter had to read the installed type definitions to find that
`agentId` lives on `<CopilotChat>` instead.

The prop publishes a bare string context (`CopilotKitAgentIdContext` in
`src/v2/context.ts`) that is the **last** fallback before
`DEFAULT_AGENT_ID`. Five resolution sites consult it:
`CopilotChatConfigurationProvider` (which covers everything nested
inside a chat), `CopilotChat`, `CopilotThreadsDrawer`, `useAgent`, and
`useSuggestions`. An explicit `agentId` still wins at every one of them.

### Why not a root `CopilotChatConfigurationProvider`

The original branch published the default by rendering a
`CopilotChatConfigurationProvider` at the root. That provider also owns
a thread: it resolves a `threadId` (minting a UUID when none is given),
and the top-most one owns the imperative active-thread override.
Wrapping the application in one hands every descendant chat the same
inherited `threadId`, so two sibling chats share a transcript.

Measured on the original branch with `randomUUID` mocked to increment:

| | sibling chat 1 | sibling chat 2 |
| -- | -- | -- |
| `<CopilotKitProvider>` | `uuid-1` | `uuid-2` |
| `<CopilotKitProvider agentId="my_agent">` | `uuid-1` | `uuid-1` |

A bare string context carries the agent default and nothing else, so the
second row now matches the first.

### Docs

- `reference/components/CopilotKit.mdx`: the callout now says it is the
v1 provider and points at `CopilotKitProvider`, followed by the
agent-prop table. The `useSingleEndpoint` row is replaced by a sentence
saying both providers negotiate the transport, with the pre-1.70.2
behavior named as history.
- `docs/backend/runtime-endpoints.mdx`: the prop rename (`agent` →
`agentId`), and the transport table and its surrounding prose corrected
for the removed pin.
- `reference/hooks/useThreads.mdx`: back to `main` (see above).

I did not rewrite the integration quickstarts that show `<CopilotKit
agent=...>`. They already carry a "Which provider goes with which
handler?" callout and pass `useSingleEndpoint={false}` explicitly, so
they are correct as written; swapping the provider in all of them is a
docs sweep of its own.

## Testing

This worktree has its own full `pnpm install` and a rebuilt workspace
`dist`, so these numbers come from a clean environment on the rebased
tree.

### Whole-package suite

Both rows are real runs in this worktree on the same rebase base, taken
by checking `main`'s `packages/react-core/src` in and out around the
run:

| | Test files | Tests | Failed |
| -- | -- | -- | -- |
| `origin/main` (31d0cda168) | 146 passed | 1639 | 0 |
| This branch | 146 passed | **1646** | 0 |

Exactly +7. Comparing the two runs' JSON reports file by file,
`CopilotKitProvider.test.tsx` (39 → 46) is the only file whose count
moved.

### The 7 new tests

```
✓ CopilotKitProvider > agentId > becomes the default agent for a chat that does not name one
✓ CopilotKitProvider > agentId > lets a nested chat configuration override it
✓ CopilotKitProvider > agentId > leaves the global default in place when the prop is omitted
✓ CopilotKitProvider > agentId > publishes no chat configuration of its own
✓ CopilotKitProvider > agentId > follows a changed agentId
✓ CopilotKitProvider > agentId > thread isolation > gives sibling chats their own thread when agentId is set
✓ CopilotKitProvider > agentId > thread isolation > matches the no-agentId tree
```

### Mutation checks

| Mutation | Result |
| -- | -- |
| drop the `providerAgentId` fallback in
`CopilotChatConfigurationProvider` | `becomes the default agent for a
chat that does not name one` and `follows a changed agentId` fail (2
failed / 44 passed) |
| publish the default through a root `CopilotChatConfigurationProvider`
instead of the bare context | `publishes no chat configuration of its
own` and both `thread isolation` tests fail (3 failed / 43 passed) |

The second mutation is the original branch's implementation, so the
thread-isolation tests fail against the code they were written to catch.

### Build, typecheck, lint, format, MDX

- `nx build @copilotkit/react-core --skip-nx-cache`: succeeds.
`context-singleton-preflight: OK — src/v2/context.ts bundled only into 4
allowed target(s)` — the new `CopilotChatConfigurationProvider` →
`../context` import does not add a bundle target.
- `tsc --noEmit -p packages/react-core/tsconfig.json`: 0 errors.
- `oxlint` on the 7 changed source files: 0 errors, and the same 9
warnings before and after (measured by checking `main`'s copies into the
same tree).
- Formatted with `oxfmt`.
- Both changed `.mdx` files compile through `@mdx-js/mdx` with
`remark-gfm`, and all 9 string assertions in `docs-render.test.ts`
against `runtime-endpoints.mdx` still hold.
- `nx test @copilotkit/react-native --skip-nx-cache`: 26 passed, 0
failed (it consumes `react-core`).

## Unrelated CI fix carried here

`doc-tests` went red on this branch for a reason that has nothing to do
with it. `@ag-ui/mastra@1.1.3` was published on 2026-09-08 at 23:19:48Z
and raised its peer range for `@ag-ui/client`/`@ag-ui/core` to
`>=0.0.58`. The Mastra doctest pins both at `0.0.57` and left the
adapter floating, so npm takes 1.1.3 and the install fails with
`ERESOLVE`. Every other open PR's `doc-tests` run that passed completed
before that timestamp — the latest at 23:13:15Z — and this branch's run
at 23:45:20Z is the first one after it, so the break lands on every PR
from here.

The second commit pins the adapter at `1.1.2`, whose peer range
(`>=0.0.44`) the existing pins already satisfy. Bumping the client and
core instead does not work: `@copilotkit/runtime@1.68.3` hard-depends on
`@ag-ui/client@0.0.57`, so raising the snippet to `0.0.59` puts two
copies of `AbstractAgent` in the tree and the snippet fails `tsc
--noEmit` with `TS2769`. Measured locally both ways — version bump
21/22, adapter pin **22/22**.

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


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

## Summary by CodeRabbit

- **New Features**
- Added provider-level default agent selection through the `agentId`
prop on `<CopilotKitProvider>`.
- Descendant chats, threads, suggestions, and agent hooks now inherit
the provider’s agent unless overridden locally.
  - Preserved separate thread identities for sibling chats.

- **Documentation**
- Updated provider migration guidance, agent naming, and automatic
endpoint detection behavior.
- Added examples for provider, subtree, and per-chat agent
configuration.

- **Chores**
  - Pinned the Mastra integration example dependency to version 1.1.2.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 20:40:39 -05:00
Tyler Slaton 902d0faea5 Point the Channels docs at an SDK pair that can render components (#6952)
## The problem

Every Channels page that tells a reader what to install named a pair
that is four minors stale:

```sh
npm install --save-exact @copilotkit/channels@0.6.1 @copilotkit/runtime@1.65.0
```

That pin is not merely old, it is load-bearing in the wrong direction.
`@copilotkit/channels@0.6.1`
does not export `defineChannelComponent`. Compiling an agent-rendered
component against the version
our own quickstart installs fails outright:

```
error TS2724: '"@copilotkit/channels"' has no exported member named
'defineChannelComponent'. Did you mean 'ChannelComponent'?
```

The export listing confirms where the boundary sits.
`@copilotkit/channels-core@0.6.1` ships
`defineChannelCommand` and `defineChannelTool` and nothing else in that
family; `defineChannelComponent`
first appears in the 0.6.2 canary line and first ships stable in 0.7.0.

So the two halves of our own documentation disagree. The Channels setup
guide gates success on "at
least one `defineChannelComponent` must render," while the reference
page and both provider
quickstarts hand the reader a version in which that success criterion
cannot be satisfied. A builder
following the docs faithfully reaches a compile error, and the error
blames their code rather than
our pin. The bad trade they make next is guessing — dropping
`--save-exact`, reaching for `@latest`,
or abandoning agent-rendered components entirely, each of which discards
the tested-pair guarantee
the pin existed to provide.

The timing is what makes this worth a same-day fix rather than a queued
one. The "Agents, Everywhere"
global hackathon runs Saturday 12 September 2026 across 51 cities with
CopilotKit as a global
sponsor, and these are precisely the pages participants will open first.

## The approach

Every pinned pair in the Channels docs moves to
`@copilotkit/channels@0.9.2` +
`@copilotkit/runtime@1.70.2`, the current published pair as of
2026-09-08. Five install lines across
the reference index, the direct-adapters reference, the
deploy-and-operate how-to, and the Slack and
Teams quickstarts.

**The pin is what changes, not the prose.** Where a page's guidance
implies agent-rendered components
are available, that guidance was already correct — it was the version
underneath it that was wrong.
Nothing about the described behaviour is edited.

**The direct-adapters availability note moves too.** It read "their
direct adapters already ship in
`@copilotkit/channels@0.6.1`," an availability claim rather than a
first-shipped-in claim, sitting
directly above an install block that now names 0.9.2. Leaving it would
make the page contradict
itself within fifteen lines.

**The SDK reference index gains the tested-pair framing it was
missing.** The quickstarts and the
deploy-and-operate page already explain that the two packages ship as a
tested pair and must be
upgraded together; the reference index pinned exact versions while
explaining nothing, which is how a
pin decays into a number nobody knows they may not touch.

**One file outside the docs content changes, and the cost is worth
naming.**
`src/lib/__tests__/channels-docs.test.ts` asserts the quickstarts
contain the exact tested install
string, so it hard-codes the pair. Updating the docs without it produces
a red PR. Only the two
version constants move; no assertion is added, removed, or loosened.

## What is not covered

- **No recording.** The change is text in six files with no runtime
surface to demonstrate. The
durable evidence is the export listing above, which is reproducible from
the registry rather than
  from this branch.
-
`showcase/shell-docs/src/content/reference/channels/functions/createChannel.mdx:114`
still reads
"Channels 0.6.1 warns when enumerable fields are dropped." This is a
behaviour-provenance note, not
an install pin, and rewriting the number would change a factual claim
about when the behaviour
changed. It needs a maintainer to say whether it means "as of 0.6.1" or
"in 0.6.1."
- `skills/setup-slack-channel/SKILL.md:81` and
`skills/setup-slack-channel/references/troubleshooting.md:8`
reference `@copilotkit/channels@0.6.0` and `@copilotkit/runtime@1.65.0`
— an even older pin, and one
the guard test explicitly calls "the broken Channels 0.6.0 release."
Same class of bug, outside docs
  content, left for a separate decision.
- The three `doctest.json` files pin `@copilotkit/runtime@1.68.3`, also
stale, also a different
  purpose.
- `CopilotKit/channels-sdk` carries the same stale install line in
  `.agents/skills/build-channels-agent/SKILL.md`. Different repository.
- The docs do not document `defineChannelComponent` anywhere, despite
the setup guide gating success
  on it. That gap is not addressed here.
- The guard test could ratchet against 0.6.1 and 1.65.0 the way it
already ratchets against 0.5.0,
0.6.0, and 1.64.2, which would stop this recurring. Deliberately not
added, to keep the diff to the
  bug.

## Verification

Registry state re-checked at edit time: `npm view @copilotkit/channels
version` → `0.9.2`,
`npm view @copilotkit/runtime version` → `1.70.2`.

Export boundary confirmed by unpacking the published tarballs:
`channels-core@0.6.1` has no
`defineChannelComponent`; `0.6.2-canary.1785779327`, `0.7.0`, `0.7.1`,
and `0.9.2` all have it.

All 10 assertions in the `channels-docs` guard test's install and
Node-version blocks were replayed
against the edited files for both provider quickstart slugs — 20 checks,
all passing. The `--save-exact`
negative lookaheads still hold: the docs contain no unpinned
`@copilotkit/channels` or
`@copilotkit/runtime` install, no `@latest` or `@next` tag, and none of
the previously blocked 0.5.0,
0.6.0, or 1.64.2 versions.

`grep` across `showcase/shell-docs/src` returns no remaining
`channels@0.6.1` or `runtime@1.65.0`.

No new test files. No source, config, or lockfile changes.


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

## Summary by CodeRabbit

* **Documentation**
* Updated channel, Slack, Teams, and direct adapter setup guides with
the latest pinned SDK versions.
* Updated the channel reference documentation to reflect the current
package versions.

* **Tests**
* Updated documentation checks to validate the newer SDK versions in
provider quickstarts.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-09 03:04:42 +02:00
Benjamin Taylor edfc7c3e17 ci(doc-tests): pin @ag-ui/mastra so the quickstart snippet resolves
`@ag-ui/mastra@1.1.3` was published on 2026-09-08 and raised its peer range
for `@ag-ui/client` and `@ag-ui/core` to `>=0.0.58`. The Mastra doctest pins
both at `0.0.57` and left the adapter floating, so npm took 1.1.3 and every
doc-tests run after the publish failed with ERESOLVE. Runs that completed
before it passed; the break is not specific to any branch.

Pin the adapter at `1.1.2`, whose peer range (`>=0.0.44`) the existing pins
satisfy, rather than bumping the client and core. `@copilotkit/runtime@1.68.3`
hard-depends on `@ag-ui/client@0.0.57`, so raising the snippet to 0.0.59 puts
two copies of `AbstractAgent` in the tree and the snippet then fails
`tsc --noEmit` with TS2769 instead. Verified both ways locally: with the
version bump 21/22 pass, with this pin 22/22 pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 18:54:04 -05:00
Benjamin Taylor e823409f96 fix(react-core): name the agent on CopilotKitProvider
`@copilotkit/react-core/v2` re-exports the v1 `<CopilotKit>` provider, and that
was the only provider carrying an agent prop. So a v2 application that wanted
to name its agent at the provider level had to reach for the v1 compatibility
component, and the reporter had to read the installed type definitions to find
that the v2 equivalent lives on `<CopilotChat agentId>` instead.

Accept `agentId` on `CopilotKitProvider`. It publishes a bare string context
that is the last fallback before `DEFAULT_AGENT_ID`, so `<CopilotChat agentId>`,
`<CopilotChatConfigurationProvider agentId>`, and an explicit `agentId` argument
to `useAgent`/`useSuggestions` all still win.

The default deliberately does NOT arrive through a root
`CopilotChatConfigurationProvider`. That provider also owns a thread: it
resolves a threadId, minting a UUID when none is given, and the top-most one
owns the imperative active-thread override. Wrapping the application in one
hands every descendant chat the same inherited threadId, so two sibling chats
share a transcript. A test renders two sibling chats under the provider and
pins that they keep their own threads.

Docs: say plainly on the `CopilotKit` reference page that it is the v1
provider, and note the prop rename on the provider-and-handler-pairs page.
Both pages claimed that released versions of `<CopilotKit>` pin
`useSingleEndpoint` to `true`; that pin was removed in 1.70.2, so both
providers now negotiate the transport when the prop is omitted.

Fixes OSS-1133

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 18:40:40 -05:00
Mike Ryan 591b3bcd53 docs: show the component tool imports for the built-in agent 2026-09-08 15:52:18 -07:00
Ben Taylor 407249d4fc fix(react-core): let a custom catch-all renderer return null (#6942)
## Summary

`useDefaultRenderTool`'s `render` was typed to return
`React.ReactElement`. A caller who wants to render only *some* tool
calls therefore could not return `null` to suppress the built-in default
for the rest — the value flowed through correctly at runtime, but the
type rejected it.

This widens the public `render` return type, and the wrapper local that
carries the user's value, to `React.ReactElement | null`.

```diff
-    render?: (props: DefaultRenderProps) => React.ReactElement;
+    render?: (props: DefaultRenderProps) => React.ReactElement | null;
```

The reference page hand-writes the same signature, so it is updated to
match, with one behavior bullet describing what `null` does.

## Scope, and its relationship to #6533

#6533 already widens the same return type to `React.ReactElement | null`
in `defineToolCallRenderer.ts` and `use-render-tool.tsx`. It does
**not** touch `use-default-render-tool.tsx`, which is the remaining gap
and the whole of this PR. There is **no file overlap**, so the two can
land in either order.

A structural sweep of `react-core/src/v2` for renders still typed `=>
React.ReactElement` with no `| null` confirms this leaves nothing behind
on this surface:

```
types/defineToolCallRenderer.ts:40,48,56   <- #6533
hooks/use-render-tool.tsx:41,72,109        <- #6533
hooks/use-default-render-tool.tsx:152      <- the deliberate bridge cast, below
hooks/use-interrupt.tsx:89                 <- different surface, out of scope
components/chat/CopilotChatMessageView.tsx:418  <- different surface, out of scope
```

The `as unknown as` cast into `useRenderTool` is deliberately left in
place: `useRenderTool` still requires a `ReactElement` return on `main`
(verified again after the rebase — `use-render-tool.tsx:41`). Once #6533
lands, that cast can be tightened. The bridge comment is updated to say
so.

`DefaultToolCallRenderer`'s own return type stays `React.ReactElement` —
the built-in default always renders an element.

The Vue counterpart needs no equivalent change: its `render` already
returns `VNodeChild`, which admits `null`, and
`reference/vue/hooks/useDefaultRenderTool.mdx` already matches.

## Why the guard is a type test, not a runtime test

TypeScript types are erased, so a `null`-returning render forwards
identically before and after the widening. The runtime test passes
against un-widened source, which makes it worthless as a guard for this
change. So the real guard is `use-default-render-tool-types.test-d.ts`,
using the `expectTypeOf` + `toEqualTypeOf` convention already documented
in `v2/__tests__/headless-type-exports.test-d.ts`.

`toEqualTypeOf` is required rather than assignability: a function
returning `ReactElement` **is** assignable to one returning
`ReactElement | null`, so an assignability check would pass against the
un-widened type and assert nothing.

The `.test-d.ts` basename is outside vitest's `include` globs, so
nothing there executes; `tsc --noEmit` (`check-types`) is what reads it.
Confirmed on this base:

```
$ vitest list --filesOnly | grep -c "test-d"
0
$ grep -n include -A4 packages/react-core/vitest.config.mjs
    include: [
      "src/**/__tests__/**/*.{test,spec}.{ts,tsx}",
      "src/**/*.{test,spec}.{ts,tsx}",
    ],
$ grep include packages/react-core/tsconfig.json
  "include": ["src/**/*"],
```

The runtime test is kept as well, since it still covers prop adaptation
and forwarding.

## Testing

All numbers below were re-measured after the rebase onto `main`
(`42494df`).

**Mutation check of the type guard** — revert the widening in the
source, confirm the guard goes red:

```
########## RUN A: rebased HEAD as-is ##########
total errors: 63
--- errors in touched files ---
  none

########## RUN B: MUTATION - widening reverted in source ##########
total errors: 65
--- guard file errors (expect FAIL) ---
use-default-render-tool-types.test-d.ts(26,3): error TS2344:
  Type '((props: DefaultRenderProps) => ReactElement<...> | null) | undefined'
  does not satisfy the constraint
  '"Expected: undefined, Actual: never" | "Expected: function, Actual: never"'.
use-default-render-tool.test.tsx(150,30): error TS2322:
  Type 'Mock<({ status }: DefaultRenderProps) => null>' is not assignable to
  type '(props: DefaultRenderProps) => ReactElement<...>'.
  Type 'null' is not assignable to type 'ReactElement<...>'.
```

The guard fails when the widening is reverted, and the two new errors
are exactly the guard plus the runtime test's own use of it. Nothing
else moves.

**Typecheck** (`tsc -p packages/react-core --noEmit`) — error set
byte-identical to pristine `origin/main` in the same worktree, none in
the touched files:

```
########## RUN C: pristine origin/main baseline ##########
total errors on pristine main: 63
=== diff: pristine-main errors vs HEAD errors ===
IDENTICAL -> the change introduces no new type errors
```

The 63 are pre-existing worktree noise: `react-core` resolves
`@copilotkit/core` and `@copilotkit/shared` from a sibling checkout's
`dist`, so unrelated exports read as missing. They are present on
pristine `origin/main` in the same worktree, which is what the diff
above shows.

**Target test file:**

```
 ✓ src/v2/hooks/__tests__/use-default-render-tool.test.tsx (13 tests) 38ms
 Test Files  1 passed (1)
      Tests  13 passed (13)
```

**Broader `src/v2/hooks` + `src/v2/types`** — failure counts identical
to pristine `origin/main` in the same worktree, plus exactly the one new
passing test:

```
=== BASELINE (pristine origin/main in this worktree) ===
 Test Files  22 failed | 17 passed (39)
      Tests  9 failed | 201 passed (210)

=== WITH my change ===
 Test Files  22 failed | 17 passed (39)
      Tests  9 failed | 202 passed (211)
```

**Lint:** `oxlint packages/react-core/src/v2/hooks/` — `Found 62
warnings and 0 errors.` (all pre-existing exhaustive-deps warnings, none
in the touched files).

**Formatting:** `oxfmt --check` on the three source/test files — `All
matched files use the correct format.` `oxfmt` does not process `.mdx`,
so the reference page is out of its scope.

**Public-API manifest:** no regeneration needed —
`scripts/release/public-api/manifest.v1.json` records no type signatures
and does not mention `useDefaultRenderTool` (`grep -c ReactElement` →
`0`).

## Provenance

Extracted from #5509 (@ataibarkai), which is 3915 commits behind `main`
and being closed. That PR also changed `defineToolCallRenderer`'s schema
default from `def.name === "*" && !def.args ? z.any() : def.args` to
`def.args ?? z.any()`. **That change is deliberately not carried here**
— it alters runtime behavior for named renderers declared without `args`
(from `args: undefined` to `args: z.any()`) and deserves its own PR and
its own verification.

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


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

## Summary by CodeRabbit

* **New Features**
* Custom renderers can now return `null` to suppress output when no UI
should be displayed.

* **Documentation**
* Updated `useDefaultRenderTool` guidance to describe null-return
behavior and selectively rendering tool calls.

* **Tests**
* Added coverage confirming null-render behavior and forwarded renderer
properties.
  * Added compile-time validation for supported renderer return types.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 17:27:44 -05:00
Benjamin Taylor 82cd7c01f7 fix(react-core): let a custom catch-all renderer return null
`useDefaultRenderTool`'s `render` was typed to return `React.ReactElement`,
so a caller who wanted to render only some tool calls could not return
`null` to suppress the built-in default for the rest. The value already
flowed through correctly at runtime; only the type rejected it.

Widen the public `render` return type, and the wrapper local that carries
the user's value, to `React.ReactElement | null`. The `as unknown as` cast
into `useRenderTool` stays, because `useRenderTool` still requires a
`ReactElement` return on main; PR #6533 widens that hook, after which the
cast can be tightened.

Guarded by a `.test-d.ts` assertion rather than a runtime test: types are
erased, so a null-returning render forwards identically before and after
the widening and a runtime test would assert nothing.

Extracted from #5509, which is otherwise stale.

Co-authored-by: Atai Barkai <atai.barkai@gmail.com>
2026-09-08 16:39:06 -05:00
Ben Taylor 30aba6b959 docs(showcase): state the frontend-tool requirement for the last nine frameworks (closes OSS-1036) (#6874)
## Problem

`generative-ui/tool-based` is the terminal page every onboarding run
fetches, on every framework route (OSS-1034). Its `## How it works in
code` section is one `<FrameworkSetup concept="frontend-tools-setup" />`
call that resolves a per-framework snippet. Nine frameworks shipped no
snippet, so the section rendered nothing and the `.md` output emitted
`<!-- setup skipped: ... -->`. That silence meant two different things
at once: "this framework needs no agent-side wiring" and "it needs
wiring and nobody wrote it down".

Verified on the live host before the change: all nine emitted the skip
comment, at ~2.4KB per page.

One of the nine is `built-in-agent`, which is `ROOT_FRAMEWORK`. So the
page carrying the gap included the unscoped default,
`https://docs.copilotkit.ai/generative-ui/tool-based.md`.

## Solution

A snippet for each of the nine. Each verdict was read out of the pinned
adapter rather than out of the docs, which is what the ticket asked for.

**Nothing to wire on the agent** — confirmed in the adapter:

| framework | the line that decides it |
| --- | --- |
| `ag2` | `autogen/ag_ui/adapter.py` `run_stream` builds `client_tools`
from `command.incoming.tools` |
| `mastra` | `@ag-ui/mastra@1.1.0` reduces `input.tools` into
`clientTools` for `agent.stream()` |
| `strands` | `ag_ui_strands@0.2.2` calls
`sync_proxy_tools(agent.tool_registry, input_data.tools, ...)` |
| `strands-typescript` | `@ag-ui/aws-strands@0.2.3` registers a proxy
tool per forwarded tool in `toolRegistry` |

Both Strands adapters refuse to overwrite a native tool of the same
name, so each snippet says to keep the `useComponent` name distinct.

**Real wiring:**

- `agno`. Its AG-UI interface never reads `RunAgentInput.tools`. Checked
against `agno==2.6.19`: the only tool path out of
`agno/os/interfaces/agui/` is
`RunPausedEvent.tools_awaiting_external_execution`. So a component needs
a declared `@tool(external_execution=True)` stub and the `Agent` needs a
`db` to hold the paused run.
- `deepagents`. `sdk-python/copilotkit/copilotkit_lg_middleware.py`
merges `copilotkit.actions` into `request.tools` inside
`wrap_model_call`, so `middleware=[CopilotKitMiddleware()]` is
load-bearing. Its snippet lives in the docs-only tree, because
`deepagents` has no integration package.

**Mode-dependent:**

- `built-in-agent`. Config mode merges `input.tools` for you
(`packages/runtime/src/agent/index.ts`). A factory owns the model call
and forwards nothing, so it has to pass them itself. Both halves are in
the snippet, plus the collision rule: a frontend tool whose name matches
a server tool is dropped in favor of the server executor.

**In-repo evidence only:**

- `ms-agent-dotnet`, `ms-agent-harness-dotnet`. Their own
`gen-ui-tool-based` agents render charts with an empty tool list
(`tools: []` / `Tools = []`) and their instructions name the chart
tools. No .NET SDK was available here to read
`Microsoft.Agents.AI.Hosting.AGUI.AspNetCore` directly.

Six of the nine snippets also carry the "Tell the model when to call it"
step, which is not filler. `GEN_UI_TOOL_BASED_PROMPT` in
`showcase/integrations/built-in-agent/src/lib/factory/demo-prompts.ts`
records what happens without it: the model emits `value: 0` for every
point and renders a chart with no bars.

## Tests

- `REQUIREMENT_NOT_ESTABLISHED` is now empty, and the docblock says a
new framework arriving without a snippet is fixed with a snippet, not
with a name.
- The shape test pins all six auto-forwarding frameworks, plus the three
that do not fit that shape (`agno`, `deepagents`, `built-in-agent`).
- `setup-concept.test.ts` used `ag2` as its example of an unbundled
concept, so closing the last gap would have turned it red for the right
reason. It now uses a concept name that is deliberately never bundled.

## The gate never ran in CI

Second commit. No workflow runs the shell-docs vitest suite:
`test_integration-docs.yml` runs exactly one test file,
`test_unit-showcase.yml` covers harness and shell-dashboard only, and
`showcase_build_check.yml` matches `showcase/**` but only builds images.
Neither path filter listed the snippet files either. So the ratchet
added in #6777 was local-only.

Added a scoped job and widened both filters. The job runs only the two
setup-concept files on purpose: the full shell-docs suite is not green
on `main`, and gating every snippet change on unrelated failures would
be worse than no gate.

## Verification

Ran against a local `shell-docs` dev server on this branch. Expected
`setup skipped` count is 0 everywhere:

```
ag2                        skip=0 bytes=3825
agno                       skip=0 bytes=4299
deepagents                 skip=0 bytes=3786
mastra                     skip=0 bytes=3857
ms-agent-dotnet            skip=0 bytes=3706
ms-agent-harness-dotnet    skip=0 bytes=4236
strands                    skip=0 bytes=4026
strands-typescript         skip=0 bytes=4001
built-in-agent (root path) skip=0 bytes=4723
```

`vitest run` on the two setup-concept files: 12 passed. `npm run
typecheck` and `npm run lint` both exit 0.

Four tests fail in the full shell-docs suite (`llm-text.test.ts` mastra
tool-rendering, three in `angular-docs-content.test.ts`). All four fail
identically at the pre-change baseline in the same worktree, so they are
pre-existing on `main` and untouched by this branch.

## Two findings this turned up, not fixed here

1. **The `agno` showcase demo contradicts its own snippet.** Every
`useFrontendTool` tool in agno's demos has a matching
`external_execution` stub, but the `useComponent` ones do not:
`render_bar_chart`, `render_pie_chart`, `query_notes` and
`highlight_note` have no backend declaration, and
`_run_main_agent_hitl_aware` in `src/agent_server.py` cannot forward
them. Its e2e spec cannot catch this, because it asserts only that an
`svg` is visible inside an assistant message, which any icon satisfies.
2. **Four frameworks redirect the HTML page away.** For `ag2`, `agno`,
`deepagents` and `mastra`, `/<slug>/generative-ui/tool-based` 301s to
`/<slug>/generative-ui/tool-rendering`. Confirmed on the live host as
well as locally, so it predates this branch. Their `.md` output serves
the page normally, which is the path onboarding runs fetch, but a human
browsing those four never reaches it.

Closes OSS-1036.


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

- **Documentation**
- Added frontend tool setup guides for AG2, Agno, Built-in Agent,
Mastra, Microsoft Agent integrations, Strands, and Deep Agents.
- Documented tool registration, prompting, execution behavior,
persistence, and middleware configuration.

- **Tests**
- Expanded coverage for frontend tool setup documentation across
supported integrations.
- Updated setup concept tests to use a stable, intentionally unbundled
example.

- **Chores**
- Added automated workflow coverage for setup documentation and related
tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 16:36:44 -05:00
Ben Taylor b0c0b50826 docs(microsoft-agent-framework): document backend approval interrupts (#6922)
Closes #2770.

## Problem

Our Microsoft Agent Framework human-in-the-loop page taught exactly one
pattern: register a frontend tool whose name matches a backend tool.
That is why #2770 was filed asking for a feature we already ship, and
why two more people asked for an update on it.

Backend-raised approvals have worked for months. Mark a tool with
`approval_mode="always_require"` (Python) or wrap it in
`ApprovalRequiredAIFunction` (.NET), and the agent ends the run with an
AG-UI interrupt that `useInterrupt` renders. No name matching. Nothing
on the docs site said so.

## What changed

Split the page the way Mastra's already is, and add the missing half:

- `human-in-the-loop/index.mdx` — picks between the two patterns. It
keeps `/microsoft-agent-framework/human-in-the-loop` resolving, so the
three existing pages that link there need no edit.
- `human-in-the-loop/interrupt-flow.mdx` — new; the approval path.
- `human-in-the-loop/tool-based.mdx` — the old page, retitled, content
unchanged.
- `custom-look-and-feel/headless-ui.mdx` — one sentence pointing backend
approvals at the new page.

The new page records four details that are easy to get wrong from
reading the source. I got each of them wrong myself before running it:

- `reason` is `"tool_call"`, not `"approval"`.
- The tool name and arguments live under `metadata.agent_framework`
**only on Python**. .NET sends no such field and names the tool in
`message`.
- `cancel()` and `resolve({ approved: false })` both leave the tool
unrun, but cancel ends the run while a false approval lets the agent
keep talking.
- `renderInChat` defaults to `true`, so the UI renders nothing —
silently, no warning — unless a `<CopilotChat />` is mounted.

## Testing

Every claim on the new page was executed, not inferred.

**End to end against a real agent.** Published `@copilotkit/react-core`
over real HTTP against a real Microsoft Agent Framework agent on
released `agent-framework-ag-ui` 1.2.2, with a tool marked
`approval_mode="always_require"`, served through the real AG-UI FastAPI
endpoint. A deterministic stub chat client stands in for the model, so
no API key is needed.

```
✓ CopilotKit <-> real Microsoft Agent Framework approval (2 tests)
  ✓ renders the backend approval and, on approve, the backend runs the tool
  ✓ on cancel, the backend does not run the tool
  Tests  2 passed (2)
```

Approving produced `TOOL_CALL_RESULT ... "content":"Deleted notes.txt."`
from the backend and surfaced it in the frontend. Cancelling produced no
tool result.

**Version floors are measured, not read off a changelog.** The same test
passes on `@copilotkit/react-core` 1.61.2 and fails on 1.61.1 (`Unable
to find an element by: [data-testid="reason"]`), which is where the
1.61.2 in the requirements table comes from. `agent-framework-ag-ui`
1.2.0 ships byte-identical interrupt-conversion logic to the 1.2.2 I
ran. `AGUI.Server` 0.0.6's shipped DLL contains the `tool_call` reason
and the `Approval required for tool call` message, and ag-ui's own
verified .NET baseline shows the same wire shape.

**Mutation-checked.** Changing the backend tool's return string fails
the approve test; clicking Approve in the cancel test fails it. An
earlier version of the cancel test passed under that mutation — it
settled with a bare `setTimeout` outside `act()` — so it was rewritten
to poll with `waitFor` and require a timeout.

**Docs suite.** Generators plus the node-environment tests that cover
routing and the nav tree:

```
 Test Files  4 passed (4)
      Tests  30 passed (30)
```
(`sitemap`, `page-tree-bridge`, `llms.txt`, `llms-mdx`)

All three routes appear in the generated search index, including the
preserved index URL:

```
microsoft-agent-framework/human-in-the-loop
microsoft-agent-framework/human-in-the-loop/interrupt-flow
microsoft-agent-framework/human-in-the-loop/tool-based
```

The jsdom-environment tests could not run locally — this checkout's
`showcase/shell-docs` install predates `jsdom`, and it resolves through
symlinks to the main checkout. CI covers them.

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


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

## Summary by CodeRabbit

* **Documentation**
* Added a Human-in-the-Loop section for Microsoft Agent Framework
integrations.
* Documented interrupt-based and tool-based workflows, including
approval, denial, cancellation, and frontend interaction guidance.
* Added details on approval-gated backend tools, interrupt payloads, and
rendering requirements.
  * Updated the tool-based guide’s title and description.
* Added the new section and page ordering to the documentation
navigation.
* Clarified how headless UI examples should render backend-tool
approvals.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 16:36:40 -05:00
Jerel John Velarde 1822de72da docs(channels): bump the tested SDK pair to channels 0.9.2 / runtime 1.70.2
The Channels pages pinned @copilotkit/channels@0.6.1 with
@copilotkit/runtime@1.65.0, four minors behind the current release.
Anyone following them installs a Channels version that predates
defineChannelComponent, which landed in 0.7.0, so agent-rendered
components cannot compile.

Update every pinned pair in the Channels docs to
@copilotkit/channels@0.9.2 + @copilotkit/runtime@1.70.2, refresh the
direct-adapters availability note that named 0.6.1, and add the
tested-pair framing to the SDK reference index, which pinned versions
without explaining that the two ship and upgrade together.

Also updates the pinned constants in the shell-docs guard test, which
asserts the quickstarts contain the exact tested install string.
2026-09-08 14:25:12 -07:00
Benjamin Taylor 0748b1a8e8 docs(showcase): explain the AgentCore 401 "Missing Authentication Token" (closes #2912)
Reporters following a framework quickstart and then pointing the runtime at a
deployed AgentCore endpoint hit `HTTP 401: Missing Authentication Token` with no
guidance anywhere in the docs. The string is AWS's own response to an unsigned
request or an unmatched route, so it reads like a CopilotKit failure when it is
not.

Add a Troubleshooting section covering the four causes: an unset
AGENTCORE_ACCESS_TOKEN interpolating to `Bearer undefined`, an expired Cognito
token, an AGENTCORE_ENDPOINT_URL that stops short of /invocations, and a browser
calling AgentCore directly instead of going through Copilot Runtime.

The AgentCore guide exists as two near-duplicate copies -- docs/deploy/agentcore.mdx
serves /deploy/agentcore, and snippets/integrations/agentcore/index.mdx is what
<Content framework="..." /> renders at /strands/deploy-agentcore and
/langgraph/deploy-agentcore. Both are live, so the section lands in both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:45 -05:00
Benjamin Taylor 5f8da811d9 docs(microsoft-agent-framework): document backend approval interrupts
Our Microsoft Agent Framework HITL page taught only the frontend-tool
approach, where the frontend registers a tool whose name matches a backend
tool. Backend-raised approvals have worked for months -- mark a tool with
approval_mode="always_require" (Python) or ApprovalRequiredAIFunction (.NET)
and the agent raises an AG-UI interrupt that useInterrupt renders -- but no
page said so, so readers kept reaching for name matching (issue #2770).

Split the page the way Mastra's is split and add the missing half:

- human-in-the-loop/index.mdx picks between the two patterns. It keeps the
  existing /microsoft-agent-framework/human-in-the-loop URL working, so the
  three pages linking there are untouched.
- human-in-the-loop/interrupt-flow.mdx documents the approval path.
- human-in-the-loop/tool-based.mdx is the old page, retitled.

The interrupt page records details that are easy to get wrong from reading
the code: reason is "tool_call" rather than "approval"; the tool name and
arguments sit under metadata.agent_framework only on Python, while .NET
names the tool in message; cancel() and resolve({approved:false}) both skip
the tool but end the turn differently; renderInChat defaults to true and
renders nothing, silently, with no chat mounted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:34 -05:00
Benjamin Taylor 2e05c9ce81 docs(showcase): put the built-in-agent name-collision rule in the right mode (refs OSS-1036)
The snippet stated the collision rule under factory mode, which implied the
runtime resolves it for you there. It does not.

Config mode is where the runtime decides: `index.ts` builds the tool set from
`convertToolsToVercelAITools(input.tools)` and then spreads the configured
tools over it, so a shared name resolves to the backend tool. The rule now
sits in that step.

In factory mode the factory owns precedence, because nothing merges the two
lists on its behalf. The showcase's own TanStack factory shows one choice,
filtering forwarded tools through `!serverToolNames.has(t.name)`, but that is
its decision rather than runtime behavior. The factory step now says so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:29 -05:00
Benjamin Taylor b3462e01fe docs(showcase): fix the using directives in the two .NET snippets (refs OSS-1036)
Both snippets named namespaces that do not resolve.

`Microsoft.Agents.AI.Harness` is the NuGet package name, not a namespace.
`AsHarnessAgent` and `HarnessAgentOptions` come from `Microsoft.Agents.AI`,
and no `.cs` file in the repo carries a `using` for the package name.

Both snippets also needed `using Microsoft.Extensions.AI`, which is where
`AsIChatClient()` and `ChatOptions` live. Every agent file in both showcase
columns uses exactly `Microsoft.Agents.AI` plus `Microsoft.Extensions.AI`.

Also define `HarnessMaxContextWindowTokens` and `HarnessMaxOutputTokens` in the
harness snippet, which referenced them without showing a value.

No .NET SDK is available here, so this was checked against the `using` blocks
of the twelve agent files that call `AsHarnessAgent`, not by compiling.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:29 -05:00
github-actions[bot] 700fb1496b style: auto-fix formatting 2026-09-08 16:22:29 -05:00
Benjamin Taylor cf060da900 docs(showcase): state the frontend-tool requirement for the last nine frameworks (closes OSS-1036)
`generative-ui/tool-based` is the terminal page every onboarding run fetches,
and its `## How it works in code` section renders a per-framework snippet.
Nine frameworks shipped no snippet, so the section rendered nothing and the
silence meant both "no agent-side wiring is needed" and "wiring is needed and
nobody wrote it down".

Each verdict was read out of the pinned adapter rather than the docs:

- ag2: `run_stream` builds `client_tools` from `incoming.tools`.
- mastra: the adapter reduces `input.tools` into `clientTools`.
- strands, strands-typescript: a proxy tool per forwarded tool is registered
  in the agent's tool registry, and a native tool of the same name wins.
- agno: its AG-UI interface never reads `RunAgentInput.tools`, so a component
  needs an `external_execution=True` stub and a `db` for the paused run.
- deepagents: `CopilotKitMiddleware` merges `copilotkit.actions` into
  `request.tools`, so the middleware is load-bearing.
- built-in-agent: config mode forwards for you, a factory does not. It is also
  the root framework, so this is the unscoped default page.

The two .NET columns rest on their own demo agents, which render charts with
an empty tool list. No .NET SDK was available to read the NuGet hosting
package.

REQUIREMENT_NOT_ESTABLISHED is now empty. The shape test pins each snippet,
and setup-concept.test.ts no longer depends on ag2 being an open gap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:29 -05:00
copilotkit-qa-bot[bot] 0f997c706e docs(strands): render subagent state in text export 2026-09-08 10:26:10 -07:00
copilotkit-qa-bot[bot] 81f43c0998 docs(strands): include subagent state helper 2026-09-08 10:00:36 -07:00
Doniyor 62c895fee2 fix(react-core): default attachment uploads to one at a time
`maxConcurrentUploads` defaulted to 3, which changed when a public
`onUpload` is called with no code change on the app's side: a handler
written when uploads were serial could suddenly see the next file start
before the previous one finished. Concurrency is now something the app
asks for, and `maxConcurrentUploads: 3` restores the pool.

Queueing the whole selection up front is kept at every limit — it shows
the user what they picked rather than changing a contract.

The default test now pins one-at-a-time; a separate test pins that
`maxConcurrentUploads: 3` really runs three. Docs, the `AttachmentsConfig`
JSDoc and the react-core skill reference say `1`.
2026-09-07 15:02:30 +05:00
Doniyor c237f29dbb fix(react-core): share the upload pool across processFiles calls
The worker pool was per `processFiles` call, so a paste landing while a
dropped selection was still uploading opened its own set of workers —
two overlapping selections could run 2× the limit, and
`maxConcurrentUploads: 1` gave one upload per call rather than one at a
time.

Move the queue and the worker count onto the hook: workers are counted,
not owned by a call, and a call tops the pool up to the limit instead of
starting a fresh one. Each call still resolves when its own files have
settled.

Also pin `Infinity` as "no limit" with a test, and say in the docs that
the limit covers everything in flight rather than each batch.
2026-09-07 15:02:30 +05:00
Doniyor 62067b76d1 feat(react-core): upload attachments concurrently
`processFiles` walked the valid files in a `for` loop and awaited each
upload inside it, so `onUpload` was called for one file only after the
previous had finished — attaching 8 files to a chat cost 8 sequential
round trips to whatever storage the app uploads to.

Queue the whole selection first, then drain it with a bounded worker
pool: `maxConcurrentUploads` on `AttachmentsConfig` sets the bound and
defaults to 3, and `1` restores one-at-a-time uploads for an endpoint
that wants them. `onUpload` may now be called concurrently.

Queueing up front also means a file waiting for a free slot is already
visible as `uploading` rather than appearing once its upload starts.

The Vue and Angular bindings read the same config type and still upload
serially; they can follow separately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 15:02:30 +05:00
Rainer Hahnekamp 0d46ef5fe7 Merge branch 'main' into feat/angular-copilot-activity 2026-09-06 21:53:17 +02:00
Tyler Slaton 9173ab479c fix(docs): address search accessibility and indexing review findings
Announce recommendation selection without invalid active descendants, omit
missing controlled elements, and cover empty-result and result-slot behavior.
Report snippet expansion failures and reject partially staged content roots
before either search index is overwritten.

Validation: 829 tests pass; three Angular/Mastra content failures already
reported in PR #6887 remain. Typecheck and lint pass (existing lint warnings).
Browser-verified local search, keyboard selection, and recommendation navigation.
2026-09-05 03:05:49 +02:00
Lukas Moschitz 45ac1b482b feat(docs): improve search ranking and recommend Intelligence guides 2026-09-05 03:05:49 +02:00
Lukas Moschitz c1086fe5fa fix(docs): index reachable pages across docs build contexts 2026-09-05 03:05:49 +02:00
Martha Kelly Schumann c70502b137 feat(inspector): add Learning view and workbench 2026-09-04 17:11:59 -07:00
Tyler Slaton e9ff66ce72 docs(integrations): state the JSON-string context contract on every agent-app-context page (#6893)
Closes OSS-1134.

## Problem

`useAgentContext` calls `JSON.stringify` on any non-string `value`
before the run leaves the browser
([`use-agent-context.tsx:29-34`](https://github.com/CopilotKit/CopilotKit/blob/main/packages/react-core/src/v2/hooks/use-agent-context.tsx#L29-L34)),
because the AG-UI protocol types `Context.value` as `z.string()` on both
ends. The Python SDK only calls `model_dump()`, so the value reaches
`state["copilotkit"]["context"]` as a JSON string with no parsing
anywhere in between.

The four reference pages have said so since b18f7054af (OSS-1003). The
**integration guides** — the pages a reader actually follows — did not,
and they walked the reader straight into the trap:

- register `colleagues`, an array of objects
- read `.get("value")` and interpolate it into an f-string

An f-string hides the type completely, because a JSON string formats
without complaint. A reader who wants `colleagues[0]["name"]` gets `'['`
instead, and the failure reads as "the frontend sent nothing" —
indistinguishable from an empty context.

## What changed

Documentation only. The wire format does not change: the string is the
protocol.

**One shared callout, eight pages.** New snippet
`snippets/shared/basics/agent-context-json-string.mdx`, imported by
every `agent-app-context` variant before its first code sample, so the
wording cannot drift. Three pages (`adk`, `crewai-flows`, `pydantic-ai`)
already stated the contract, but only *after* their first code sample,
where a reader skimming to the code misses it.

**Four examples were wrong, not just undocumented:**

| Page | Defect | Fix |
|---|---|---|
| langgraph (Python) | interpolated the raw string | `json.loads`, then
reads `c["name"]` so the reason to parse is visible |
| langgraph (TypeScript) | `find` predicate was `'The current user\'s
colleagues"'` — a stray quote that could never match | predicate
corrected, then `JSON.parse` |
| mastra | `JSON.stringify(item?.value)` on an already-encoded value →
double encoding | parses instead |
| ag2 | returned the raw string at three sites, one annotated `->
list[dict]` | all three parse |

The langgraph TypeScript predicate bug meant that example could not have
worked as printed, independently of the JSON issue.

Reference pages are untouched — all four already cover this correctly.

## Testing

**Acceptance criteria, checked mechanically against the final content:**

```
=== AC1: callout precedes the first code fence, all 8 variants
  PASS adk        PASS ag2          PASS built-in-agent   PASS crewai-flows
  PASS langgraph  PASS mastra       PASS ms-agent-fwk     PASS pydantic-ai
=== AC2: no context value interpolated without a parse
  PASS (all 8; every ag2 extraction assigns to `raw`, then json.loads(raw))
=== AC3: nothing stringifies an already-string value
  PASS (swept every .mdx under docs/ and snippets/)
```

**The edited code actually runs.** Executed the Python and TypeScript
fragments as printed:

```
compiles: langgraph / ag2 get_readable / ag2 list_colleagues
round trip OK; None default still absorbed by the call site's `or []`
chat_node   -> 'John Doe (Developer), Jane Smith (Designer)'
mastra      -> 'John Doe (Developer), Jane Smith (Designer)'
pre-fix colleagues[0] was '[' (a single character)
pre-fix mastra output: "[{\"id\":1,\"name\":\"John Doe\",\"role\":\"D...   (double encoded)
pre-fix langgraph TS find predicate matched: false (was always undefined)
```

The last three lines reproduce the reported failure and both latent
bugs, then show them fixed.

**MDX renders.** All 9 files compiled through the real pipeline
(`inlineSnippets` → `convertTablesInJSX` → `@mdx-js/mdx`), with zero
snippet-resolution warnings:

```
PASS × 9   snippet warnings: (none)
```

**Test suite — failure-set diff, not a bare pass.** This environment has
a known install-staleness gap (`@clerk/nextjs`), so I compared against a
pristine-content baseline in the same worktree rather than against zero:

```
baseline (pristine main content):  Test Files  14 failed | 68 passed (82)   Tests 35 failed
with this change:                  Test Files  14 failed | 68 passed (82)   Tests 35 failed
FAILURE-SET DIFF: IDENTICAL — this change introduces no new failure
```

For reference, the same content passes cleanly where the install is
complete: 51 files / 351 tests, matching its own baseline exactly.

**Mutation-checked the probes** rather than trusting a green light:
breaking the snippet import path fails 1 page, and deleting the callout
text fails all 6 dependents — confirming the snippet is genuinely shared
and the checks can actually fail.

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


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

## Summary by CodeRabbit

* **Documentation**
* Added guidance across integration guides clarifying that agent context
values arrive as JSON strings.
* Added parsing examples for Python and TypeScript, including
colleague-list formatting.
* Added warnings about avoiding raw access and double-encoding context
values.
* Updated AG2, LangGraph, and Mastra examples to parse context values
before use.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-05 01:39:23 +02:00
Tyler Slaton 97d1379ae8 feat(docs): improve page prompt actions 2026-09-05 01:24:50 +02:00
Tyler Slaton 282e8f1c11 feat(docs): make quickstart and learning product first 2026-09-05 01:24:50 +02:00
Tyler Slaton 79c683bb2c feat(docs): refine navigation and Intelligence hierarchy 2026-09-05 01:24:50 +02:00
Tyler Slaton 21ac18fba6 fix(docs): center reading layout and mobile toc 2026-09-05 01:24:50 +02:00
Ben Taylor 8c629c147b docs(showcase): document frontend-driven activity cards (refs #3388) (#6904)
## What

Issue #3388 asked for a way to put a card into the chat transcript from
frontend code, without a tool call and without adding to the
conversation the model reads.

**That already ships.** A message with `role: "activity"` renders
standalone in the transcript, and `AbstractAgent.prepareRunAgentInput`
strips every activity message from the run payload:

```js
prepareRunAgentInput(e) {
  let t = structuredClone_(this.messages).filter(e => e.role !== `activity`);
  ...
}
```

The gap was documentation. `renderActivityMessages` is only documented
for **backend-emitted** activities (mastra background-tasks, a2a,
mcp-apps), so the frontend-driven path was undiscoverable.

This PR adds the missing guide page and a test that pins the behavior.

## Changes

| File | Why |
| --- | --- |
| `showcase/shell-docs/.../generative-ui/frontend-cards.mdx` | New
"Frontend-Driven Cards" guide |
| `showcase/shell-docs/.../generative-ui/meta.json` | Sidebar entry
(6-line insertion) |
| `packages/react-core/.../CopilotChatFrontendActivityCard.e2e.test.tsx`
| Pins both halves of the contract |

No source changes. Behavior is unchanged; this documents and locks what
already works.

## The non-obvious part

The card must be added via the agent returned by `useAgent()`. An agent
instance constructed and held outside React is **not** the instance the
chat renders, so messages added to it silently never appear. This cost
me a debugging round while verifying, and it is called out as a warning
callout in the docs.

## Testing

**1. New test passes against clean `origin/main`** (run in a worktree at
`96cf7aa55f`, with `@copilotkit/shared` and `@copilotkit/core` rebuilt
from the worktree so the test is not reading a stale dist):

```
✓ src/v2/components/chat/__tests__/CopilotChatFrontendActivityCard.e2e.test.tsx (2 tests) 72ms

 Test Files  1 passed (1)
      Tests  2 passed (2)
```

**2. Mutation-checked, so neither assertion is self-fulfilling.**

Drop the renderer registration → the render test fails:
```
× renders a card added from frontend code, with no tool call 1068ms
      Tests  1 failed | 1 passed (2)
```

Swap the card from `role: "activity"` to `role: "assistant"` → it
reappears in the payload, so the exclusion is real and specific to
`activity`:
```
AssertionError: expected [ 'user', 'assistant' ] to deeply equal [ 'user' ]
```

**3. Neighboring test unaffected on the same base:**

```
✓ src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx (16 tests) 53ms
      Tests  16 passed (16)
```

**4. Independent probe of the filter** against the pinned
`@ag-ui/client` 0.0.57:

```
agent.messages roles: [ 'user', 'activity' ]
run input roles     : [ 'user' ]
```

**5. `tsc --noEmit`** — zero errors in the new file. Remaining errors in
this workspace are in files this PR does not touch
(`MCPAppsActivityRenderer.tsx`, `CopilotKitInspector.tsx`) and are
artifacts of a hand-assembled local `node_modules`; CI has the real
install.

**6. `oxfmt --check`** — clean.

**7. Docs checks** — `meta.json` validated as JSON; internal link uses
the house `/generative-ui/...` form (no `/docs` prefix); `Callout
type="warn"` matches the dominant existing usage; import paths verified
against the real `@copilotkit/react-core/v2` barrel exports.

## Follow-up

Leaving #3388 open until this lands, then closing it with a pointer to
the new page.

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

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

## Summary by CodeRabbit

- **New Features**
- Added support for frontend-driven activity cards that render in chat
transcripts without being sent to the agent or language model.
- Added documentation covering activity card renderers, schemas,
registration, payload filtering, snapshots, and limitations.
- Added a new “Frontend-Driven” section to the Generative UI
documentation navigation.

- **Tests**
- Added end-to-end coverage for activity card rendering and payload
exclusion.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-04 17:32:15 -05:00
Manfred Steyer 603bdb4e12 Update showcase/shell-docs/src/content/reference/angular/components/CopilotActivity.mdx
Co-authored-by: Rainer Hahnekamp <rainer.hahnekamp@gmail.com>
2026-09-05 00:02:56 +03:00
Benjamin Taylor 28a19ddfa2 docs: document controlling the chat open state from your own UI
Leads the "Open, close, and feedback" page with the `open` /
`onOpenChange` pair and an example driving the sidebar from a nav button
outside it, which is the case #3334 asked about. The existing
`useCopilotChatConfiguration` route stays, now framed as the option for
callers who would rather not lift the state.

Also corrects `defaultOpen` on the CopilotSidebar and CopilotPopup
reference pages: both documented `false`, but both surfaces mount open.
2026-09-04 15:12:11 -05:00
Benjamin Taylor 3672d007ae docs(showcase): document frontend-driven activity cards, lock the behavior with a test
Activity messages (role: "activity") already render standalone in the
transcript and are stripped from the run payload by
AbstractAgent.prepareRunAgentInput, so frontend code can put a card in the
chat without a tool call and without polluting the conversation. That was
only ever documented for backend-emitted activities, so the frontend-driven
path was undiscoverable — issue #3388 asked for a feature that already ships.

Adds a Generative UI guide page for the pattern and a react-core test that
pins both halves of the contract: the card renders, and it never reaches the
agent.

The non-obvious part, and the reason this needs documenting rather than a
one-line answer: the card must be added via the agent from useAgent(). An
agent instance constructed and held outside React is not the instance the
chat renders, so messages added to it silently never appear.

Refs #3388

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 15:05:30 -05:00
Mike Ryan 37703eb083 Support Intelligence over the single Runtime route (#6896)
## Summary

- carry Intelligence thread, memory, and annotation requests through the
single Runtime endpoint
- advertise the bridge through an optional Runtime info capability
- reuse the existing REST route matcher, handlers, method checks, hooks,
and memory gate
- route Core memory and React annotation calls through the negotiated
Runtime fetch
- make single-route the documented Intelligence quickstart while keeping
multi-route supported

## Compatibility

- Multi-route behavior does not change.
- A new client uses the bridge only when a single-route Runtime
advertises it.
- An old client ignores the new optional capability.
- A new client keeps the old behavior with a Runtime that does not
advertise the capability.

## Validation

- `pnpm nx run-many -t check-types,build
--projects=@copilotkit/shared,@copilotkit/core,@copilotkit/runtime,@copilotkit/react-core`
- package pre-commit gate: tests, `publint`, and `attw` passed for all
affected packages
- Runtime focused suite: 102 tests passed
- Core focused suite: 108 tests passed
- React focused suite: 53 tests passed
- React full suite: 1,591 Vitest tests and 47 script tests passed
- Angular and React memory tests: 18 tests passed
- docs type-check and production build passed
- changed docs contract tests: 33 tests passed

## Local baseline notes

The full docs test command also reads Git LFS images and generated
cross-framework fixtures. It has six unrelated failures in this
checkout: three image-pointer checks, two Angular content checks, and
one Mastra content check. The changed docs tests pass, and the docs
production build passes.


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

- **New Features**
- Added single-route support for thread, memory, and annotation
operations.
- Runtime capability discovery now advertises single-route resource
support.
- Resource requests preserve paths, query parameters, headers, methods,
and request bodies.
- Memory and annotation operations consistently use the configured
runtime transport.

- **Documentation**
- Updated setup guides for single-route configuration, capability
negotiation, and compatibility.
  - Added guidance for single-route LangGraph deployments.

- **Tests**
- Added coverage for transport behavior, validation, resource
operations, and error handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-04 11:33:44 -07:00
Tyler Slaton e1a6225afc docs: streamline Learning workflow explanation 2026-09-04 20:09:01 +02:00
Tyler Slaton b0035f2b78 docs: simplify Intelligence Learning guide 2026-09-04 20:09:01 +02:00