mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
codex/fac-202-shared-state-rendering
5430 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
29cf68640a | fix(docs): preserve complete production code blocks | ||
|
|
f712369889 | Merge remote-tracking branch 'origin/main' into codex/fac-197-state-snapshot-docs | ||
|
|
be5315556c | docs(crewai): verify AG-UI endpoint before cloud setup | ||
|
|
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 --> |
||
|
|
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
|
||
|
|
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 |
||
|
|
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 --> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
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>
|
||
|
|
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> |
||
|
|
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>
|
||
|
|
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` (
|
||
|
|
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 --> |
||
|
|
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> |
||
|
|
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> |
||
|
|
591b3bcd53 | docs: show the component tool imports for the built-in agent | ||
|
|
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 --> |
||
|
|
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> |
||
|
|
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 --> |
||
|
|
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 --> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
700fb1496b | style: auto-fix formatting | ||
|
|
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> |
||
|
|
0f997c706e | docs(strands): render subagent state in text export | ||
|
|
81f43c0998 | docs(strands): include subagent state helper | ||
|
|
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`. |
||
|
|
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. |
||
|
|
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> |
||
|
|
0d46ef5fe7 | Merge branch 'main' into feat/angular-copilot-activity | ||
|
|
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. |
||
|
|
45ac1b482b | feat(docs): improve search ranking and recommend Intelligence guides | ||
|
|
c1086fe5fa | fix(docs): index reachable pages across docs build contexts | ||
|
|
c70502b137 | feat(inspector): add Learning view and workbench | ||
|
|
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
|
||
|
|
97d1379ae8 | feat(docs): improve page prompt actions | ||
|
|
282e8f1c11 | feat(docs): make quickstart and learning product first | ||
|
|
79c683bb2c | feat(docs): refine navigation and Intelligence hierarchy | ||
|
|
21ac18fba6 | fix(docs): center reading layout and mobile toc | ||
|
|
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 --> |
||
|
|
603bdb4e12 |
Update showcase/shell-docs/src/content/reference/angular/components/CopilotActivity.mdx
Co-authored-by: Rainer Hahnekamp <rainer.hahnekamp@gmail.com> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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 --> |
||
|
|
e1a6225afc | docs: streamline Learning workflow explanation | ||
|
|
b0035f2b78 | docs: simplify Intelligence Learning guide |