- Remove 'rename' from the prebuilt CopilotThreadsDrawer capability claims
(guide, React reference, shared Threads callout) — the row kebab only does
archive/unarchive + delete. Add an explicit note that rename is available via
the headless useThreads path. (MikeRyanDev)
- Reference CSS parts list now matches the shipped element: adds row/row-active,
collapse-toggle, close-toggle, backdrop, launcher-cluster, launcher-new-thread,
load-more, fetching-more, fetch-more-error, fetch-more-retry, licensed,
licensed-cta; grouped by area. (MikeRyanDev)
- Rewrite the 'no threadId state / no onSelect plumbing' line to stand on its own
by contrasting with a hand-rolled sidebar. (samjulien)
Stand-in for a live showcase example (out of scope for this PR): a real
screenshot of <CopilotThreadsDrawer> beside <CopilotChat>, rendered from the
v2 react demo against the Intelligence platform. Embedded as a <Frame> preview
right under the intro.
Match the final component name. Renames the guide and reference pages
(copilot-drawer.mdx -> copilot-threads-drawer.mdx, CopilotDrawer.mdx ->
CopilotThreadsDrawer.mdx), their slugs/URLs, the nav meta entry, the
data-testid default, the <copilotkit-threads-drawer> element mention, and
all prose/import references. The --cpk-drawer-* CSS tokens and ::part names
are unchanged.
Per review: remove the onUnlicensed prop, the unlicensed slot, and the
unlicensed/unlicensed-cta parts from the guide + reference so neither
humans nor agents surface them. Replace with a single neutral line:
threads require Intelligence; a locked view shows without a license key.
- Guide: lead with the user benefit (less reference-y opening), reframe the
headless useThreads alternative to stand alone, add the OpsPlatformCTA
sign-up callout (per review).
- Add threads.mdx (shared-snippet include) for a2a, adk, agent-spec,
deepagents + register each under Intelligence Platform in meta.json.
Per review: defer the Angular drawer docs. Removes the Angular reference
page, the guide's Angular section, and Angular cross-links; keeps the
React guide + reference + the Threads how-to callout.
- Add full StateGraph + Annotation setup with CopilotKitStateAnnotation.spec
- Show complete tool implementation with proper ToolMessage handling
- Include graph compilation with nodes, edges, and routing logic
- Pattern examples after working shared-state-streaming.ts reference
- Fix both Deep Agents and LangGraph docs versions
- Include formatter fixes for JSON files
Fixes FAC-101
- Replace incorrect StateSchema API with Annotation.Root
- Fix undefined modelWithTools variable (use model directly)
- Add missing imports (ChatOpenAI, SystemMessage, RunnableConfig)
- Correct StateGraph constructor to use (annotation, { input, output })
- Handle response.content type conversion properly
- Update comments to reflect actual TypeScript API
The example now matches the actual @langchain/langgraph TypeScript API
as used in the showcase integrations, making it copy-pasteable and
functional.
Resolves FAC-113
Fixes TS4111 error in strict TypeScript configurations by using bracket
notation (process.env['PORT']) instead of dot notation (process.env.PORT)
for environment variable access.
Fixes: FAC-86
## Problem — the leak
The v2 runtime's `shouldForwardHeader` forwarded `authorization` **and
any header whose name starts with `x-`** onto the outgoing agent call.
In a real deployment the inbound request has already traversed a
browser, CDN/edge, load balancer, and hosting platform — each stamping
its own `x-*` headers — so the wide `x-*` wildcard silently forwarded:
- **Hop-by-hop / topology:** `x-forwarded-for`, `x-real-ip`,
`x-forwarded-proto/host/port`
- **Cloud / CDN tracing:** `x-amzn-trace-id`, `x-amz-cf-id`,
`x-cloud-trace-context`, `x-azure-*`, `x-fastly-*`, `x-request-id`
- **Platform-injected:** `x-vercel-*`, `x-middleware-*`
- **CopilotKit Cloud platform credential:**
`x-copilotcloud-public-api-key`
The last item is a real credential-exfiltration concern: a platform key
scoped to Copilot Cloud reaching a third-party agent URL. This is the
**breadth** half of #5712 (option 3); the **precedence** half was fixed
in #5782.
## Design — denylist default + config knob, both paths
- **Default denylist (safe default).** Keep the `authorization` + `x-*`
base eligibility, but strip a curated, greppable set of known
infra/proxy/platform headers (exact names + prefix families) before
forwarding. Legitimate custom `x-*` application headers (`x-tenant-id`,
`x-api-key`, …) keep flowing untouched. The authoritative list is a
single exported constant in `header-utils.ts`.
- **Configurable policy (`forwardHeaders` runtime option).**
- `useDefaultDenylist?: boolean` (default **true**) — `false` restores
the previous wide-open behavior.
- `deny?` / `denyPrefixes?` — extend the default denylist.
- `allow?` — opt into strict allowlist mode (only listed headers
forward).
- **Resolve once.** The constructor resolves `forwardHeaders` into a
`forwardHeadersPolicy: ResolvedForwardHeadersPolicy` field (mirroring
the existing `debug` → `ResolvedDebugConfig` resolve-once), exposed on
`CopilotRuntimeLike` / `BaseCopilotRuntime` with a passthrough getter on
the `CopilotRuntime` shim.
- **Both paths.** The resolved policy is read at **/run**
(`configureAgentForRequest`) and **/connect** (`handleSseConnect`) via
`mergeForwardableHeaders`, so the two can never diverge. Server-wins
precedence and server-self case-dedup from #5782 are untouched.
## Semver
**Minor with an opt-out.** Removing a leak is a fix, not a contract
change, and we ship a documented escape hatch: `new CopilotRuntime({
agents, forwardHeaders: { useDefaultDenylist: false } })` restores the
prior behavior. Custom-header forwarders (the common case) are
unaffected.
## Red-green proof (real surface, both paths)
RED — with the predicate reverted to the old wide-open `authorization ||
x-*` (policy ignored), the new behavior assertions fail; the leak
reproduces (`x-forwarded-for: 203.0.113.7` forwards on both /run and
/connect):
```
❯ header-utils.test.ts (19 tests | 8 failed)
× strips known infra/proxy/platform headers by exact name → expected true to be false
× strips known infra/platform header families by prefix → expected true to be false
× strips denylisted headers case-insensitively → expected true to be false
× deny extends the default set → expected true to be false
× denyPrefixes extends the default set → expected true to be false
× allow switches to allowlist mode → expected true to be false
× extractForwardableHeaders drops denylisted x-* infra → expected {…4} to deeply equal {…1}
❯ agent-utils-header-forwarding.test.ts (/run) (10 tests | 1 failed)
× strips denylisted infra/platform headers (#5712 breadth) → expected '203.0.113.7' to be undefined
❯ sse-connect-agent-id.test.ts (/connect) (5 tests | 1 failed)
× strips denylisted infra/platform headers → expected '203.0.113.7' to be undefined
```
GREEN — with the real policy in place:
```
✓ header-utils.test.ts (19 tests)
✓ agent-utils-header-forwarding.test.ts (10 tests) # /run path
✓ sse-connect-agent-id.test.ts (5 tests) # /connect path
✓ agent-header-precedence.test.ts (2 tests)
Test Files 4 passed (4)
Tests 36 passed (36)
```
Full `@copilotkit/runtime` suite: **113 files / 1593 tests passed.**
Typecheck, oxlint (0 errors), oxfmt, and build all green.
## Builds on #5782
This branches off #5782's head (`636bcad05`) and reuses that PR's
`mergeForwardableHeaders` (server-wins precedence + server-self
case-dedup). It should land **after #5782**. It addresses the
**forwarding-breadth half of #5712** — #5712's precedence core is fixed
by #5782; this is the breadth follow-up (not `Fixes #5712`).
Document the v2 runtime's inbound-header forwarding behavior on the
Copilot Runtime page: the default denylist (authorization + x-* minus
known infra/proxy/platform headers), the x-request-id upgrade note,
server-configured header precedence (#5782), and the forwardHeaders
config option (deny/denyPrefixes/allow/useDefaultDenylist) with the
allowlist-mode denylist-bypass footgun.
Refs #5712, #5783
The "Using setThreadId" example called useCopilotContext, which is a
v1-only hook not exported from @copilotkit/react-core/v2, causing a
build error. The preceding "Dynamically Switching Threads" section
already documents the correct threadId + setThreadId state pattern.
Closes#3860
## Summary
The `attachments` prop supports images, audio, video, and documents —
but the JSDoc example in `Chat.tsx` only showed
`image/*,application/pdf`, and the docs configuration example used
`accept: image/*`, silently teaching users to restrict themselves to
images.
**Before (Chat.tsx JSDoc):**
```tsx
accept: image/*,application/pdf,
```
**After:**
```tsx
accept: image/*,audio/*,video/*,application/pdf,
```
The docs configuration example now also clarifies that omitting `accept`
defaults to `*/*` (all files), and the shown value includes all four
supported modalities.
## Changes
- `packages/react-ui/src/components/chat/Chat.tsx` — updated JSDoc
example to show all modalities; added note that default `accept` is
`*/*`
- `showcase/shell-docs/src/content/docs/multimodal-attachments.mdx` —
updated configuration example to show
`image/*,audio/*,video/*,application/pdf` and note that omitting
`accept` allows all types
## Summary
- Fix six instances of `recieve`/`Recieving` → `receive`/`Receiving`
plus `manaully` → `manually` and `procuct` → `product` across the README
and the live shell-docs source.
- All changes are pure spelling corrections — no semantic, structural,
or behavioral edits.
- One of the typos (`procuct`) sits in the README's **Self-Learning
Agents** section, which is rendered on the public GitHub project page;
the rest are in user-facing tutorials (LangGraph AI travel app, A2A
agentic protocol).
### Files changed
- `README.md` — `procuct` → `product`
- `showcase/shell-docs/src/content/docs/agentic-protocols/a2a.mdx` —
`recieved` → `received`
-
`showcase/shell-docs/src/content/docs/integrations/langgraph/tutorials/ai-travel-app/step-5-stream-progress.mdx`
— `Recieving`/`manaully`/`recieve` → `Receiving`/`manually`/`receive`
-
`showcase/shell-docs/src/content/docs/integrations/langgraph/tutorials/ai-travel-app/step-6-human-in-the-loop.mdx`
— three `recieve`/`recieves` → `receive`/`receives`
Per [CONTRIBUTING.md](../blob/main/CONTRIBUTING.md), I only edited
`showcase/shell-docs/src/content/` (the canonical docs source) and
avoided both the retired top-level `docs/` folder and the `ag-ui/`
upstream-mirrored folder.
## Validation
- `pnpm exec oxlint README.md` → `Found 0 warnings and 0 errors.`
- `pnpm exec oxfmt --check README.md` → `All matched files use the
correct format.`
- `pnpm exec commitlint --from HEAD~1 --to HEAD` → passes (subject
conforms to `@commitlint/config-conventional`).
- Repo-wide re-grep for the fixed typos in
`showcase/shell-docs/src/content/` and `README.md` → no remaining
matches.
### Note on local pre-commit hook
The `lefthook` `test-and-check-packages` hook unconditionally runs `pnpm
run test && pnpm run check:packages` on every commit. On my machine that
transitively triggers `nx run @copilotkit/core:build`, which crashes
inside `@rolldown/binding-darwin-arm64@1.0.0-rc.3` under Node v25.9.0
(this reproduces on plain `main` without any of my changes — it is a
pre-existing native-binding incompatibility unrelated to a docs-only
edit). I committed with `--no-verify` for that reason; the relevant
`lint-fix` hook (oxlint + oxfmt against staged files) passed cleanly. CI
will of course run on the project's pinned Node version.
## Checklist
- [x] I have read the [Contribution
Guide](https://github.com/CopilotKit/CopilotKit/blob/main/CONTRIBUTING.md)
- [x] If the PR changes or adds functionality, I have updated the
relevant documentation — N/A, this PR *is* the documentation fix
- [x] "Allow edits by maintainers" is checked
Made with [Cursor](https://cursor.com)
Follow-up to the sharedStateStreamingAgent commit.
- fixture: key the confirmation leg on the updateWorkingMemory toolCallId
(ordered before the leg-1 entry) instead of hasToolResult. hasToolResult is
a thread-global predicate, so in the sequential 3-pill D6 probe pill 2's
leg-1 stopped matching once pill 1 left a tool result in the thread. The
toolCallId anchor keeps each pill's two legs disambiguated across the
interleaved conversation (matches the langgraph-python gold pattern).
- docs: add shell-docs shared-state/predictive-state-updates.mdx ("State
streaming") documenting the Mastra updateWorkingMemory -> STATE_DELTA path,
at parity with the 7 other integrations that ship this page; registered in
the shared-state meta.json.
Manifest parity bar = every demo backed by demo + aimock e2e + doc. The
background-agents cell had demo + e2e but no shell-docs page. Authored
background-tasks.mdx (mirrors the interrupt-flow doc structure: What/When/
Steps/Give-it-a-try) covering the backgroundable tool flag, instance
BackgroundTaskManager, agent wiring, and the renderActivityMessages activity
card — plus an honest 'Completion is out of band' section documenting the
untilIdle-needs-a-worker finding. Added to the nav under the Mastra section.
Drop the bespoke 'Mastra bridge' phrasing (used nowhere else in the mastra
docs — they say 'embed a Mastra agent in Copilot Runtime' / 'Mastra natively
supports AG-UI'). Show tracingOptions the canonical way, inside
new CopilotRuntime({ agents: MastraAgent.getLocalAgents({ mastra, ... }) }),
matching quickstart.mdx + shared-state/*.mdx, instead of a bare getLocalAgents.
The v1 bridge (@ag-ui/mastra 1.1.0-alpha.0) emits reasoning start/content/end
and STATE_DELTA shared-state streaming, so the already-wired demos + e2e +
aimock fixtures go live. Moves out of not_supported_features into features:
- agentic-chat-reasoning, reasoning-default-render, tool-rendering-reasoning-chain (OSS-384)
- shared-state-streaming (OSS-423)
Adds the missing reasoning-default / reasoning-custom manifest demo entries.
not_supported_features now holds only gen-ui-interrupt + interrupt-headless,
matching the langgraph-python gold standard, which quarantines the same two
cells on an upstream @copilotkit/react-core v2 resume-path hook bug (published-
package fix, out of scope). The native interrupt + RUN_FINISHED outcome path
ships in the bridge; the showcase cell is blocked by the same upstream bug.
Adds an OSS-424 execution-tracing note (tracingOptions inbound / traceId on
RUN_FINISHED.result outbound) to the Mastra Copilot Runtime doc.
## Problem
Docs OG image generation was producing unreliable social-preview output
for docs URLs. The route depended on old static OG assets and Inter-era
styling, and the preview did not match the current CopilotKit docs theme
or logo.
## Why
The OG route should render a consistent branded card from page
frontmatter for every docs slug. It also needs local render assets for
request-time reliability: `next/og` does not inherit the app layout
font, and image inputs need to be available as bytes when the route
renders.
## Fix
- Reworked `showcase/shell-docs/src/app/og/[...slug]/route.tsx` to
render a branded 1200x630 card with a tighter layout, CopilotKit theme
colors, Plus Jakarta Sans, and per-page title/description/section
labels.
- Kept `next/font/google` for normal docs pages, and added upstream Plus
Jakarta Sans static TTFs only for the OG renderer. `SOURCE.md` records
the upstream URLs and SHA-256 hashes. The Google Fonts variable TTF was
tested but the bundled `next/og` renderer crashes while parsing its
`fvar` table.
- Added the official CopilotKit full lockup as a real PNG asset. It is
covered by the repo-level `*.png filter=lfs` rule, and the route encodes
the PNG bytes to a data URI only at render time for `ImageResponse`.
- Removed the hardcoded runtime/frontend/agent pills and the yellow
gradient stop from the card.
- Updated the focused OG route test to assert the card dimensions and
bundled Plus Jakarta fonts.
Validation: focused OG test, direct `ImageResponse` render with the
upstream fonts, lint, typecheck, build, and live local OG route checks
passed. Full shell-docs test has unrelated existing failures in public
LFS PNG assets and one docs-render nav expectation.
Address review feedback on the OpenBox Governance recipe:
- Replace the ASCII flow with a real inline-SVG architecture diagram
- Condense the wall-of-text provisioning warning to a few lines
- Convert the governance-matrix table into per-prompt accordions
- Highlight the key lines across the code samples to guide the reader
- Move the coding-agent prompt to the top in a collapsed accordion
The OpenBox Governance recipe (#5686) merged ahead of its companion
showcase (#5685), so the "Get the code" link pointed at
github.com/.../tree/main/examples/showcases/openbox-governed-copilotkit,
which 404s while that code is not yet on main.
Replace the broken link with a plain "Full source to follow" note (no
hyperlink, so nothing 404s) that still describes what the showcase will
contain. The live upstream reference-repo link is kept. Swap the link
back in once the showcase merges to main.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fr5HVeDzDyC4S6DjyhAFWZ
## What
Removes the `@copilotkit/bot-store-redis` and
`@copilotkit/bot-store-postgres` adapters, added in #5613. The pluggable
`StateStore` interface and the in-memory `MemoryStore` default stay;
durable backends can be reintroduced as a follow-up when there's a
concrete need.
## Why
Both adapter packages were merged but **never published to npm**, so
there are no consumers — removal is a clean delete with no migration or
deprecation cycle. Trimming the surface keeps the bot persistence story
to one well-tested in-memory default plus a documented "bring your own
`StateStore`" path.
## Changes
- Delete `packages/bot-store-redis` and `packages/bot-store-postgres`.
- Revert the `bot` release scope and the release drift-guard test to
`bot + bot-ui` (count 2).
- Strip the Redis dependency, `demo:restart` script, restart demo,
`docker-compose.yml`, and `REDIS_URL` env from `examples/slack`.
- Rewrite the bot persistence/transcripts docs around "MemoryStore
default + implement the `StateStore` interface yourself for durability"
(unrelated enterprise/Helm Redis/Postgres docs untouched).
## Verification
- `nx run @copilotkit/bot:build` — pass
- `nx run @copilotkit/bot:test` — 121/121 pass
- Release drift guard — pass at count 2
- Repo-wide grep for
`bot-store-redis|bot-store-postgres|createRedisStore|createPostgresStore`
— zero matches
The StateStore interface and the in-memory MemoryStore default remain;
durable backends can be reintroduced as a follow-up. Both adapter packages
were merged in #5613 but never published to npm, so removal is a clean
delete with no consumer impact.
- Delete packages/bot-store-redis and packages/bot-store-postgres.
- Revert the bot release scope and drift guard to bot + bot-ui.
- Strip the Redis dep, demo:restart script, restart demo, docker-compose,
and REDIS_URL env from examples/slack.
- Rewrite the bot persistence/transcripts docs around "MemoryStore default
+ implement the StateStore interface yourself for durability".
Bring the agnostic root A2UI docs up to the catalog-on-provider model and
make every generated framework serve them consistently.
- Root /generative-ui/a2ui (index, fixed-schema, dynamic-schema): lead with
passing a catalog on the provider (auto-enables A2UI and auto-injects the
generate_a2ui tool), add a manual opt-out section explaining the two pieces
you wire yourself (the generate_a2ui agent tool and the A2UIMiddleware), and
set fixed-schema to injectA2UITool: false since the agent owns the tool.
- Flip langgraph-fastapi, strands, strands-typescript to docs_mode: generated
so they serve the shared root A2UI docs 1:1 with langgraph-python.
Generated frameworks covered: langgraph-python/fastapi/typescript, google-adk,
strands, strands-typescript. deepagents (authored) is handled separately.
Rewrites the Microsoft Teams guide for the new `@copilotkit/bot-teams`
adapter added in #5497.
The existing guide documented an older API (`createTeamsAgentBot`, a
local "Teams DevTools" bridge) that shipped through copilotkitnext and
no longer matches the package. This rewrites it to mirror the Slack
guide:
- Quickstart with `createBot` + the `teams()` adapter, verified in the
M365 Agents Playground (no Microsoft account)
- Interactive Adaptive Cards with inline `onClick` handlers
- A human-approval gate via `thread.awaitChoice`
- Splitting the bot from its agent over AG-UI
- Azure sideloading into real Teams (tunnel, Entra app, Azure Bot,
manifest)
Also refreshes the frontend picker summary (Playground, not DevTools).
### Merge ordering
This depends on #5497. The Teams guide is an `earlyAccess` page, so it
should not go live until `@copilotkit/bot-teams` actually publishes.
**Merge this after #5497 ships the package.**
## Summary
- Moves the canonical `/threads` guide into the **Build Chat UIs** nav
group, immediately after prebuilt components
- Keeps `/premium/threads-explained` under **Intelligence Platform** as
the architecture/persistence explanation
- Adds contextual cross-links between the Threads guide, Threads
architecture page, and relevant prebuilt chat UI docs
- Shows `Threads` in the authored framework sidebars next to their chat
UI basics
## Why
Threads are primarily discovered by developers adding saved
conversations, history, and thread switching to a chat UI. The
implementation guide belongs with chat UI docs, while the platform page
remains the deeper explanation of persistence, realtime sync, and
Enterprise Intelligence Platform backing.
## Screenshots
**Root docs navigation: `/threads` now appears with the chat UI basics,
immediately after Prebuilt Components.**

**Authored framework navigation: framework-specific docs now show
Threads next to Prebuilt Components too.**

**Intelligence Platform navigation: the architecture page stays in the
platform section.**

## Validation
- `git diff --check origin/main...HEAD`
- `git diff --check`
- `npm run typecheck` from `showcase/shell-docs`
- Local route smoke checks for `/threads`, `/premium/threads-explained`,
`/prebuilt-components`, and `/prebuilt-components/chat` returned 200
- Authored framework route smoke checks returned 200