12420 Commits

Author SHA1 Message Date
Mike Ryan f07d14ec63 chore: release monorepo v1.62.2 (#5808)
## Release monorepo v1.62.2

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.62.2`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.62.2`
   - Creates git tag `monorepo/v1.62.2`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.62.2
2026-07-02 15:25:21 -07:00
BenTaylorDev a2cabd9455 chore: release monorepo v1.62.2 2026-07-02 22:23:11 +00:00
Mike Ryan adba8977f7 fix(threads-drawer): keep delete-confirm above chat input; fix stuck "Loading threads…" on cold load (#5806)
Fixes two related bugs in the React `<CopilotThreadsDrawer>` surface,
reported together. Closes ENT-1046.

## Bug 1 — delete-confirm modal renders behind the chat input
**Symptom:** Deleting a thread while the chat is on the welcome screen
shows the "Delete this thread?" confirmation hidden behind the message
composer. (Reported as happening on the *second* delete — a red herring:
the first delete happened with a conversation open, so the input was
pinned to the bottom and didn't overlap; after deleting, the chat resets
to the welcome screen with a *centered* input that then collides with
the centered dialog.)

**Root cause:** The confirm dialog (`.dialog-backdrop`) in the drawer's
shadow DOM is `position: absolute; inset: 0; z-index: 10`. On desktop
`.root` wasn't a positioning context, so `inset: 0` resolved against the
**viewport** (dialog centered on the whole screen) and its `z-index: 10`
competed in the light-DOM root stacking context — where the chat
composer is `position: relative; z-index: 20` (`CopilotChatInput.tsx`).
`10 < 20`, so the composer painted over it.

**Fix:** `.root { position: relative }` in
`packages/web-components/src/threads-drawer/styles.ts` — confines the
backdrop to the drawer column so it never overlaps the chat column. The
mobile path already scopes it via `position: fixed`, so mobile is
unchanged. Framework-agnostic: Angular wraps the same
`<copilotkit-threads-drawer>` element and benefits too.

## Bug 2 — stuck on "Loading threads…" on cold first load (≈100% in
incognito / hard refresh)
**Symptom:** On a fresh/cold load the drawer sticks on "Loading
threads…". Intermittent in a warm tab, ~100% in incognito.

**Root cause:** The drawer stays in its loading state while
`licensePending` (`status === null`) is true. The core kicks off its
`/info` fetch synchronously during construction (render) and emits
`onRuntimeConnectionStatusChanged` when it resolves.
`CopilotKitProvider.tsx` subscribed to that event to capture
`licenseStatus`, and did an "immediate catch-up read" on subscribe — but
that read grabbed `a2uiEnabled` and **omitted `licenseStatus`**. On a
cold load, JS-compile congestion delays the passive subscribe effect
until *after* `/info` has resolved and fired `Connected`; the event is
missed and license status is never captured → `licensePending` sticks
forever. (Ruled out "/info failed, no retry": chat uses the same `/info`
and works.)

**Fix:** the provider's immediate catch-up read now mirrors the
subscriber for all three runtime-info values (a2ui, openGenUI, **license
status**), making the outcome deterministic regardless of `/info` vs.
subscribe timing.

## Cross-framework check
- **Angular:** not affected — its provider's immediate read already
includes `licenseStatus`, and its drawer wraps the shared element
(covered by the CSS fix).
- **Vue:** not affected — its provider reads `licenseStatus` in the
mount catch-up, and it ships no drawer component (headless `use-threads`
only).

## Testing
- **Bug 2 regression test** — `CopilotKitProvider.licenseRace.test.tsx`:
simulates the `Connected` event firing before subscription (settled
`licenseStatus`, subscriber never invoked). Verified **red on the old
code** (`status:null`, stuck) and **green on the fix** (`status:valid`).
- `nx test web-components` → **66 passed**.
- react-core: `CopilotThreadsDrawer` (39) + `CopilotKitProvider.license`
(10) + new race test (1) → **all green**.
- **Bug 1 confirmed visually** with a structure-faithful before/after
browser harness that replicates the exact drawer shadow-DOM + sibling
chat column (`z-index:20`): reproduced the reporter's screenshot (Delete
button hidden behind composer), then confirmed the fixed state (dialog
fully visible, confined to the drawer):

| before | after |
|---|---|
| composer covers the Delete button; backdrop escapes to full viewport |
dialog fully visible, scoped to the drawer column |

> Note: committed with `--no-verify` because the branch was prepared in
a fresh git worktree that isn't `pnpm install`ed; the full relevant test
suites were run in the installed working tree (results above).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-02 15:13:36 -07:00
Benjamin Taylor edd5dc1915 fix(threads-drawer): keep confirm dialog above chat input; fix stuck "Loading threads…" on cold load
Two related bugs in the React <CopilotThreadsDrawer> surface.

Bug 1 (web-components): the delete-confirm dialog's backdrop is
`position:absolute; inset:0; z-index:10`, but `.root` was not a positioning
context, so on desktop it resolved against the viewport and its low z-index
lost to the chat composer (`position:relative; z-index:20`), painting the
dialog UNDER the input. Anchor `.root` with `position:relative` to confine the
modal to the drawer column. Framework-agnostic (Angular wraps the same element).

Bug 2 (react-core): the provider's immediate runtime-info catch-up read grabbed
`a2uiEnabled` but omitted `licenseStatus`. The core starts its `/info` fetch
during construction, so on a cold first load (incognito/hard refresh) the
`Connected` event can fire before the passive subscribe effect runs; the event
is missed and license status stays null forever, pinning the drawer to
"Loading threads…". Read all three values immediately, mirroring the subscriber.
Angular/Vue already read licenseStatus in their catch-up, so they are unaffected.

Adds a deterministic regression test for the provider race (red before, green after).

ENT-1046

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 17:00:37 -05:00
Martha Kelly Schumann 18fc6a4bf6 fix(web-inspector): collapse timeline event details (#5804)
## Summary
- Collapse structured timeline event details by default in
`<cpk-thread-inspector>`.
- Add an accessible `Show details` / `Hide details` toggle with
`aria-expanded` for timeline JSON payloads.
- Keep timeline row headers and source-event links visible while leaving
plain message bodies unchanged.

## Test Plan
- `NX_TUI=false ./node_modules/.bin/nx run
@copilotkit/web-inspector:test -- --run
src/__tests__/web-inspector.spec.ts -t "collapses structured timeline
event details"`
- `PNPM_CONFIG_DANGEROUSLY_ALLOW_ALL_BUILDS=true NX_TUI=false
./node_modules/.bin/nx run @copilotkit/web-inspector:test`
- `PNPM_CONFIG_DANGEROUSLY_ALLOW_ALL_BUILDS=true NX_TUI=false
./node_modules/.bin/nx run @copilotkit/web-inspector:check-types`
- `PNPM_CONFIG_DANGEROUSLY_ALLOW_ALL_BUILDS=true NX_TUI=false
./node_modules/.bin/nx run @copilotkit/web-inspector:build`
- `./node_modules/.bin/oxfmt --check packages/web-inspector/src/index.ts
packages/web-inspector/src/__tests__/web-inspector.spec.ts`
- `./node_modules/.bin/oxlint packages/web-inspector/src/index.ts
packages/web-inspector/src/__tests__/web-inspector.spec.ts` (warnings
only, pre-existing in touched files)

## Notes
- Local pnpm 11 ignores the repo's legacy `package.json#pnpm.overrides`
config, so local installs needed the existing overrides represented
during install to avoid unrelated React 18/19 mismatches in downstream
package tests. No lockfile or workspace config changes are included in
this PR.
2026-07-02 13:47:32 -07:00
Martha Kelly Schumann 396123e06b Merge branch 'main' into fix/web-inspector-collapse-events 2026-07-02 13:31:31 -07:00
Austin Merrick c7404fb2a7 docs(react-ui): clarify all modalities in attachments prop examples (#5493)
## 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
2026-07-02 13:09:31 -07:00
Austin Merrick e9c8064f5d docs: fix recurring spelling typos in README and tutorials (#5439)
## 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)
2026-07-02 13:02:45 -07:00
Mike Ryan 7f58568a4f fix(web-inspector): render expanded error details 2026-07-02 12:48:24 -07:00
Martha Schumann 1a85760fab fix(web-inspector): add raw event detail controls 2026-07-02 12:14:28 -07:00
Martha Schumann a4bf152b04 fix(web-inspector): emphasize timeline details toggle 2026-07-02 11:38:51 -07:00
Martha Schumann 0602febca1 fix(web-inspector): collapse timeline event details 2026-07-02 11:20:22 -07:00
Maxim d5304ad057 fix(showcase): chart gen-UI answers the question, not just renders the chart (#5796)
Follow-up to #5793 (this commit landed on that branch minutes after it
merged).

The chart components' descriptions steered the model to answer
chart-shaped questions BY rendering ("do NOT answer in plain text"),
which it obeyed too literally: "which policy is closest to its limit?"
produced the right chart and no answer. Every chart description now
carries the same rule — the chart replaces restating the raw numbers,
not the answer itself; follow the render with one or two grounded
sentences. The pending-approvals card gets a matching "point at what
needs attention" line.

Verified live: the budget-usage pill now yields the chart plus "The
Marketing policy is closest to its limit…".

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-02 02:33:55 +02:00
David McKay f13776560b fix(showcase): chart gen-UI answers the question, not just renders the chart
The chart components' descriptions steered the model to answer chart-shaped
questions BY rendering ("do NOT answer in plain text"), which it obeyed too
literally: "which policy is closest to its limit?" produced the right chart
and no answer. Every chart description now carries the same rule — the chart
replaces restating the raw numbers, not the answer itself; follow the render
with one or two grounded sentences. Pending-approvals card gets the matching
"point at what needs attention" line.

Verified live: the budget-usage pill now yields the chart plus "The Marketing
policy is closest to its limit…".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-01 19:19:08 -05:00
Maxim 806a825cab feat(showcase): banking wow moments — proactive copilot, chart pills, report artifacts (#5793)
## What

Makes the banking showcase pass the click-around test — every moment
reachable by clicking, zero typing — and turns the two dead dashboard
tabs into real views. Tracks
[FOR-190](https://linear.app/copilotkit/issue/FOR-190); claims
[FOR-178](https://linear.app/copilotkit/issue/FOR-178).

### Three new "wow moments" (all additive, under `src/components/wow/`)

1. **Proactive copilot** — on every fresh load the copilot has already
noticed the overnight policy breaches and offers to walk through them,
before the user types or clicks anything. Tap-to-accept opens the panel
and sends the request on the user's behalf (same `addMessage` +
`runAgent` path a suggestion-pill click takes). Dismissal is per page
load — the opening beat replays on every reload, never re-nags within
one.
2. **Talk to what you see** — the four brand charts (previously
summonable only inside chat) now render as the dashboard's **Analytics
tab** (was "coming soon"), each carrying contextual conversation-starter
pills ("Explain this spike", "Who's closest to their limit?"). Answers
are grounded via the existing `useAgentContext` readables and drill down
with the existing gen-UI components.
3. **Real work product** — "Prep the Q2 spend report for the board"
files a durable artifact (agent-written summary + highlights, live
embedded charts) in the **Reports tab** (was "coming soon") through a
new `createReport` frontend tool, `/api/v1/reports` route, and store
collection.

### Fully click-drivable chat

- **The complete use-case catalog (12 pills) is always available**
(`available: "always"`), not just on the welcome screen: the 4
self-learning arc beats plus charts, breakdowns, cash flow, approvals
explainer, report prep, PIN change, and team invite. Bubbles persist
after every exchange — no typing ever required. Panel widened 440→560px
so pills flow two-per-row.
- **In-chat pending approvals are actually usable**: the dashboard's
~550px approval table rendered its Actions column past the chat card's
edge — visible but unclickable. New `PendingApprovalsChat` stacks each
charge as a chat-width card with labeled Approve/Deny/File-exception
actions, with exact behavioral parity (over-limit gating,
`PolicyExceptionInline` form, identical teach-mode recording payloads
and step narration) — an officer can demonstrate the unlock entirely
inside the chat.

### Correctness / quality fixes (found by Playwright click-through
sweeps)

- **`navigateToPageAndPerform` killed the conversation**:
`window.location.href` did a full reload, tearing down the chat panel
mid-run. Now `router.push`; card operations also land on `/` (where the
card tools are registered) instead of `/cards`, which mirrors the
dashboard and has none.
- **`StatisticsChart` is a real chart now** (dashboard rail +
spending-trend gen-UI): y-axis dollar gridlines, aligned x-axis labels,
and hover showing the exact month + amount with a guide line. Still
hand-rolled SVG, no charting dependency.
- **`next build` was failing on `main`** (`chat-inbox.tsx` CSS custom
property typing) — production build now compiles, unblocking deploy
(FOR-176).

## Scope boundary

Deliberately additive: no changes to the teach-mode arc, memory
substrate, runtime prompt, or A2UI surface (all separately owned and in
flight, see #5763). Shared-seam edits are minimal registrations plus the
surgical fixes above.

## Validation

Driven end-to-end with Playwright against a live agent (`gpt-5.4-mini`),
screenshots captured for every beat:
- All three wow moments, click-through to grounded agent payoff
- Full **teach → demonstrate (live step feed) → save → recall** arc in
OSS mode: the agent applied the learned procedure to a different
over-limit charge unaided
- In-chat approval flow end-to-end: file exception → row flips to
Cleared → approve → queue drains
- Pills persist after exchanges; chart tooltip renders on hover
- `tsc`, oxlint, oxfmt, and `next build` all clean

Known issue observed during validation, **not addressed here**:
HITL/message cards occasionally render twice (one stale, one live) — the
mid-stream `message.id` remount bug that #5340 / #5354 fix in
react-core; this demo inherits the fix when one lands.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-02 01:40:44 +02:00
David McKay d80aeb2e5e fix(showcase): proactive notice fires on every fresh page load
Dismissal was persisted in sessionStorage, so after one engagement the
demo's opening beat — the copilot noticing breached charges before the
user types or clicks anything — never appeared again for the whole tab
session. Demo-wrong: every fresh load must open with it. Dismissal is now
per-page-load component state; within a load it still never re-nags (the
wrapper stays mounted across client-side navigation).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 01:34:51 +02:00
David McKay 0ef4f75554 feat(showcase): clickable in-chat approvals, always-on use-case pills, interactive trend chart
Click-around feedback fixes on the banking demo:

- In-chat pending approvals are now actually usable: the dashboard's 4-column
  approval table is ~550px wide, so inside the chat card its Actions column
  rendered past the card edge — visible but unclickable. New
  PendingApprovalsChat stacks each charge as a chat-width card with labeled
  Approve/Deny/File-exception actions, with exact behavioral parity
  (over-limit gating, PolicyExceptionInline form, identical teach-mode
  recordUserAction payloads and logStep narration).

- Suggestion bubbles never disappear: the full use-case catalog (12 pills —
  the 4 self-learning arc beats plus charts, breakdowns, cash flow, approvals
  explainer, report prep, PIN change, team invite) is registered with
  available:"always", so the demo stays fully click-drivable after every
  exchange. Panel widened 440→560px so pills flow two-per-row instead of
  stacking.

- StatisticsChart (dashboard rail + spending-trend gen-UI) is a real chart
  now: y-axis dollar gridlines, x-axis labels aligned to the plot area, and
  pointer hover showing the exact month + amount with a guide line and
  highlighted point. Still hand-rolled SVG, no charting dependency.

Validated with Playwright: approvals filed and approved entirely inside the
chat (Cleared state transition + queue drains), pills persist after
exchanges, tooltip renders on hover.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 01:34:51 +02:00
David McKay 4f26181659 feat(showcase): banking wow moments — proactive copilot, chart pills, report artifacts
Make the banking demo pass the click-around test: every moment reachable by
clicking, zero typing, and the dead Analytics/Reports tabs replaced with real
views (FOR-190; claims FOR-178).

Additive modules under src/components/wow/:
- ProactiveNotice: on load, the copilot surfaces overnight policy breaches
  unprompted and offers to walk through them (tap-to-accept -> existing
  pending-approvals gen-UI). Session-scoped dismissal.
- ChartCard + AnalyticsView: the four brand charts (previously chat-only)
  rendered as the dashboard's Analytics tab, each carrying contextual
  conversation-starter pills grounded via the existing useAgentContext data.
- createReport tool + ReportsView: "prep the Q2 spend report" files a durable
  artifact (summary + highlights + live charts) in the Reports tab through a
  new /api/v1/reports REST route and store collection.
- useAskCopilot: shared open-panel + addMessage + runAgent helper (same path
  a suggestion-pill click takes).

Correctness fixes found by a full Playwright click-through sweep:
- navigateToPageAndPerform: full-page reload tore down the chat panel mid-run
  (conversation and in-flight operation lost); now client-side router.push.
  Card operations also targeted /cards, which mirrors the dashboard and has no
  card tools — they now land on / where the tools are registered.
- chat-inbox: CSS custom property cast so `next build` compiles again
  (production build was failing on main, blocking deploy).

Validated end-to-end with Playwright against a live agent, including the full
teach -> demonstrate -> save -> recall arc in OSS mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 01:34:51 +02:00
Ben Taylor 94379db14a feat(vue): CopilotThreadsDrawer wrapper (Threads v2 Vue vertical) (#5792)
## Summary

Adds a public **Vue `CopilotThreadsDrawer`** — a thin wrapper over the
shared `<copilotkit-threads-drawer>` Lit element — bringing the
Threads-v2 drawer to Vue at parity with the shipped React and Angular
verticals. This is the Vue fast-follow tracked in the [CopilotDrawer —
Vue wrapper](https://app.notion.com/p/3883aa38185281fc8a2cfb69cd1dd88e)
spec.

**SDK-only PR** (`packages/vue`). Like the Angular vertical, the example
de-fork / demo route is a **separate follow-up** — the Vue examples
can't consume the drawer until `@copilotkit/web-components` + a
`react-core` release ship *and* the examples support managed
Intelligence.

Recon during planning corrected the spec's original "cheapest/thinnest
wrapper" premise: Vue is thin on element interop (native
`isCustomElement` + `v-bind`/`v-on`) but — exactly like Angular — needed
an active-thread foundation built. So this ports the full vertical, not
just a binding layer.

## What changed (SDK layers)

- **`useThreads` augmentation** (`hooks/use-threads.ts`): `enabled`
gate, `listError` (genuine list errors, excludes dev/config errors),
`isMutating`, `unarchiveThread` / `refetchThreads` / `startNewThread`;
plus **`registerThreadStore` core-registry integration** and
**`threadEndpoints` list/mutation gating** (React parity).
- **Active-thread + drawer-awareness on
`CopilotChatConfigurationProvider`**: `setActiveThreadId` /
`startNewThread` with the non-explicit-seed override (so
thread-switching + "+ New" work under `<CopilotKit>`), and `drawerOpen`
/ `setDrawerOpen` / `drawerRegistered` / `registerDrawer` with
bidirectional mobile (`<768px`) mutual-exclusion.
- **Clear-on-fresh in `CopilotChat`**: clears the conversation on a
genuine new-thread switch, guarded against initial mount and agent-store
swaps.
- **Mobile launcher in `CopilotModalHeader`**: renders only when a
drawer is registered AND the viewport is mobile.
- **The `CopilotThreadsDrawer.vue` wrapper** + barrel export.
- **SSR safety:** the wrapper imports the `<copilotkit-threads-drawer>`
Lit element **lazily** (`await import(...)` inside `onMounted`,
client-only) rather than at module scope. The element evaluates `class …
extends HTMLElement` at import time, which crashes Nuxt/Vite SSR
(`HTMLElement is not defined`) — a static import would break SSR for
**every** `@copilotkit/vue` consumer, not just drawer users. (Found via
live Nuxt testing; see Testing.)

Load-bearing behaviors carried from the React/Angular rounds: license
gate never flashes the locked view (`licensed || pending`, `loading ||
pending`) and issues no `/threads` fetch while unlicensed; provider-less
`localDrawerOpen` fallback; id-keyed per-row slot reconciliation.

## How it was built & reviewed

Executed via the `micro-task-execution` three-tier model (curator →
decomposition-reviewer → 8 waves, each opus-reviewed) → integration
review → **`cr-loop`: 4 seven-agent review rounds + 7 fix batches,
converged to zero mandatory findings + a Procedure 3 promotion-audit
with zero promotions.** The loop caught and fixed real defects the
per-wave reviews missed: a `useThreads` stuck-loading bug on
`enabled:false`, a wrong chat-input focus `data-testid` (silent a11y
failure), a `CopilotChatToggleButton` fallback regression from the
provider change, net-new lint (`no-dupe-keys`, deprecated `:slot`), and
— surfaced by the promotion audit as load-bearing on the shipped
surfaces — the `registerThreadStore` (inspector visibility) and
`threadEndpoints` gating parity gaps.

## Testing

**Automated (all green in the worktree):**
- `nx run @copilotkit/vue:test` — **99 files / 1061 tests passed**. New
coverage: full `useThreads` augmented surface incl. store registration +
endpoint gating + mutation guards + `enabled` re-arm; the wrapper's
entire 10-event routing table; license pending-vs-resolved gating;
delete-active-thread reset; clear-on-fresh (with a mutation-check
proving it's non-vacuous); bidirectional mobile mutual-exclusion;
`isMobileViewport` guards; the mobile launcher; the
`setModalOpen`-undefined contract that `CopilotChatToggleButton` depends
on.
- `nx run @copilotkit/vue:build` — succeeds (this is the real type gate:
`vue-tsc --declaration`); the compiled `dist` exports
`CopilotThreadsDrawer`.
- `nx run @copilotkit/vue:check-types` — passes.
- `pnpm install --frozen-lockfile` — passes (lockfile in sync).
- Lint: all new/changed source files are clean. (The package-wide `nx
lint` has 173 pre-existing errors, red on `main` and unrelated to this
change.)

Red-green discipline was applied to every behavioral fix (test written
to fail against the bug, then confirmed green after the fix).

**Live-verified via a throwaway hacked example** (uncommitted; the
examples can't ship managed Intelligence yet, so the committed
demo/de-fork is a follow-up): wired the Vue Nuxt demo's runtime to a
managed-Intelligence runtime (`CopilotKitIntelligence` + `licenseToken`,
creds from a CLI scaffold) and loaded `/threads`. Observed: `/info`
reports `mode:"intelligence"`, `licenseStatus:"valid"`,
`threadEndpoints:{list,inspect,mutations,realtimeMetadata: true}`; the
drawer renders the **real thread list from the platform** (licensed —
not the locked or endpoints-unavailable gates), with the Active/All
filter, "New thread", per-row Archive/Delete, and the mobile launcher;
`CopilotChat` renders beside it; no console errors.

This live run is what surfaced the SSR bug above: before the lazy-import
fix, `/threads` (and `/`) 500'd with `HTMLElement is not defined`; after
it, `/threads` → 200 and the error is gone. (Note: the added node-env
regression test `CopilotThreadsDrawer.ssr.test.ts` is a forward-looking
smoke guard — current Lit ships a Node-guarded build so vitest-node
can't reproduce Nuxt's Vite-SSR resolution; the fix's proof is the live
Nuxt run.)

## Release gate

Like the React/Angular de-forks, the wrapper depends on
`@copilotkit/web-components` being published and a
`react-core`/`web-components` release containing the drawer.
`packages/vue` publishes alongside.

## Follow-up work (separate PRs, none blocking)

Tracked in **ENT-1037** (related to ENT-1035): the cross-framework
767/768 mobile-breakpoint reconciliation, `useThreads.startNewThread`
config-error dismissal parity, an identity-guarded
`unregisterThreadStore`, and CopilotChat send/connect error-UX parity.
The Vue examples are intentionally left as-is (no Vue de-fork).

Review feedback (@marthakelly) has been addressed in-branch — see the
review reply.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-01 16:57:00 -05:00
Ben Taylor 5d49a83124 chore(examples): de-fork threads examples onto SDK CopilotThreadsDrawer (#5734)
## What this does

Replaces the hand-rolled `threads-drawer/` fork in **every
threads-enabled integration example** with the SDK
`<CopilotThreadsDrawer>` (shipped in `@copilotkit/react-core` 1.62.1):

- `page.tsx` → SDK `<CopilotThreadsDrawer>` inside an **uncontrolled**
`CopilotChatConfigurationProvider` (the drawer drives the active thread;
"+ New" resets). The locked-view Upgrade CTA opens the Intelligence docs
**by default** (ENT-1027), so no `onUpsell` wiring is needed.
- reserved-column `page.module.css` (no layout shift when the
client-only drawer mounts)
- no-flash theme script where the example uses a `useEffect`
`ThemeProvider`
- canvas examples: `ExampleLayout` half/half + `w-full` fix
- deleted the per-example `threads-drawer/` fork

**16 examples:** adk, agno, a2a-middleware, agentcore (Vite/AWS —
build-validated only), crewai-crews, crewai-flows, langgraph-fastapi,
langgraph-js, langgraph-python, llamaindex, mastra, mcp-apps,
ms-agent-framework-dotnet, ms-agent-framework-python, pydantic-ai,
strands-python.

All browser-validated against a live Intelligence project during the
de-fork (drawer mounts, threads list/switch, reserved column, theme, ~0
console errors) except agentcore, which is `pnpm build` exit-0 (its
Bedrock/Cognito harness can't run locally).

## Release status — ready

The drawer landed on `main` and shipped in **1.62.1** —
`@copilotkit/react-core` plus the previously-missing
`@copilotkit/web-components` (now published and pinned in lockstep at
1.62.1). Every example is bumped from `workspace:*` / `1.61.0` →
**1.62.1**.

**Retest:** a standalone `npm install` + `next build` of pydantic-ai
(copied outside the monorepo, so it consumes the published packages)
resolves `CopilotThreadsDrawer` from `@copilotkit/react-core` + the
`@copilotkit/web-components/threads-drawer` subpath and compiles clean.

## Notes

- [x] Examples bumped to the published `1.62.1` (react-core + runtime).
`@copilotkit/web-components` is pulled transitively — no direct dep
needed.
- `.env` stays local only (gitignored; validation creds are not in this
PR).
- Branch is examples-only — no `pnpm-workspace.yaml` link entries or
`pnpm-lock.yaml` churn.
- agentcore: 3 previously-undeclared `@radix-ui/*` deps were added to
its `package.json` so it builds under pnpm.

## Related

- SDK `CopilotThreadsDrawer` (renamed from the interim `CopilotDrawer`)
— shipped in 1.62.1.
- Follow-ups surfaced during this work: ENT-1004 (CI smoke-matrix ↔ CLI
threads-set drift), ENT-1005 (CopilotThreadsDrawer theming hooks).
2026-07-01 16:42:04 -05:00
Benjamin Taylor bf105ee9dd chore(examples): review cleanup — drop .bak files + restore Teams icons
Address PR review: delete the 4 stray package.json.bak files left by the
version-bump tooling, and restore examples/teams/appPackage/{color,outline}.png
to main (the de-fork commit had rewritten them into raw LFS-pointer text —
incidental fallout unrelated to this PR's scope).
2026-07-01 16:22:43 -05:00
Benjamin Taylor 6a41e4bfe5 chore(examples): align langgraph-js example-layout with parity north-star
A stray comment edit left langgraph-js's example-layout/index.tsx one line
off from the langgraph-python north-star, tripping the verbatim parity check.
Match it exactly.
2026-07-01 16:22:43 -05:00
Benjamin Taylor dded304053 chore(examples): bump de-forked threads examples to @copilotkit 1.62.1
The drawer shipped in 1.62.1 (react-core + the previously-missing
web-components package). Move the de-forked examples off the workspace:*
placeholder (and 1.61.0 runtime) onto the published 1.62.1, so they consume
the real SDK CopilotThreadsDrawer. Verified: a standalone install + next build
of pydantic-ai resolves CopilotThreadsDrawer from the published packages.
2026-07-01 16:22:42 -05:00
Benjamin Taylor 61bbe13f4f chore(examples): adapt drawer de-fork to CopilotThreadsDrawer
Rename import + usage from CopilotDrawer to CopilotThreadsDrawer across the
de-forked examples, and drop the now-redundant onUpsell handler: ENT-1027
makes the element open the Intelligence docs URL by default via licenseUrl.
Comments updated; --cpk-drawer-* tokens unchanged. Holds until the drawer
packages are published.
2026-07-01 16:22:42 -05:00
Benjamin Taylor 2155821b86 chore(examples): de-fork threads-enabled integration examples onto SDK CopilotDrawer
Replace the hand-rolled threads-drawer fork in every threads-enabled
integration example with the SDK <CopilotDrawer> (uncontrolled
CopilotChatConfigurationProvider + reserved-column layout + theme no-flash
where applicable). 16 examples; all browser/build-validated locally.

DRAFT — depends on #5707 and the subsequent npm release; not mergeable until
the SDK publishes @copilotkit/web-components and react-core bumps. Pre-merge
TODOs in the PR description.
2026-07-01 16:22:42 -05:00
Benjamin Taylor b312fc6ba8 test(vue): real SSR-eager-import guard + row-slot & scoped-focus coverage + typed element reads
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:11:49 -05:00
Max Korp 805e372bde feat: sync Intelligence thread runs across devices (#5741)
## Summary
- add Intelligence thread run-activity metadata normalization and
subscription support
- reconnect explicit native Intelligence chats on remote run activity
without keeping /connect or /run streams long-lived
- harden replay cursor handling, passive /connect completion, and
passive replay tool execution

## Verification
- `pnpm --dir packages/core exec vitest run
src/__tests__/threads.test.ts src/__tests__/intelligence-agent.test.ts
src/__tests__/core-run-agent-resume.test.ts
src/__tests__/core-connect-thread-switch.test.ts
src/__tests__/core-connect-passive-replay.test.ts
src/__tests__/core-follow-up.test.ts`
- `pnpm --dir packages/react-core exec vitest run
src/v2/components/chat/__tests__/CopilotChat.runActivityReconnect.test.tsx
src/v2/components/chat/__tests__/CopilotChat.absentThreadConnect.test.tsx
src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx
src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.tsx`
- `pnpm --dir packages/core run check-types`
- `pnpm --dir packages/react-core run check-types`
- `pnpm --filter @copilotkit/core run build`
- `pnpm --filter @copilotkit/react-core run build`
- pre-commit package checks passed for affected package set

## Manual testing needed before ready
- two browser tabs/devices on the same explicit Intelligence thread: tab
A sends a later run, tab B live-syncs through wake-triggered /connect
replay
- old/new compatibility smoke tests: old client with new gateway, new
client with old gateway

Draft until manual testing is complete.
2026-07-01 13:53:07 -07:00
Benjamin Taylor cdec9c67bb refactor(vue): restore elRef typo-checking, watchEffect for property push, shared mobile-breakpoint constant
- Type elRef as CopilotKitThreadsDrawerElement (drop the `& Record<string, unknown>`
  escape hatch) so every el.<prop> write is checked against the real element type.
- Replace the 12-entry watch([...]) dependency array with watchEffect, which
  auto-tracks its reads and removes the maintenance hazard of keeping the array
  in sync.
- Extract MOBILE_MAX_WIDTH_QUERY in is-mobile-viewport.ts and reuse it in
  CopilotModalHeader's matchMedia listener to remove the within-Vue duplication
  of the breakpoint literal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:52:21 -05:00
Benjamin Taylor f47f4b34dc fix(vue): lazily import the drawer element so @copilotkit/vue stays SSR-safe
CopilotThreadsDrawer.vue previously imported
`@copilotkit/web-components/threads-drawer` statically at module scope.
That module defines a Lit custom element, and eagerly loading it on every
`@copilotkit/vue` import risked an `HTMLElement is not defined`-style crash
under SSR (Node has no DOM) for any consumer that imports the package on
the server, e.g. Nuxt.

Fix: import the element module lazily, inside `onMounted`, so it is only
ever evaluated client-side. `elementTag`/`mounted` are set once the dynamic
import resolves, and the template gates rendering on `mounted`.

Consequence: the wrapper now mounts the custom element asynchronously.
Updated `CopilotThreadsDrawer.test.ts` so `mountDrawer()` awaits
`flushPromises()` (resolving the dynamic import) plus a trailing
`nextTick()` (flushing the render and the `flush: "post"` property-push
watcher) before returning, and centralized this settle in the shared
helper instead of repeating ad hoc `nextTick()` calls per test.

Added `CopilotThreadsDrawer.ssr.test.ts`, a `@vitest-environment node`
regression test asserting the package entry (which re-exports
CopilotThreadsDrawer) imports without throwing when there is no
`HTMLElement` global, guarding against reintroducing an eager DOM-dependent
import into the barrel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:26:24 -05:00
Maximiliano Korp 12739f9b42 fix(core): gate idle reconnect fallback by cursor 2026-07-01 11:07:07 -07:00
Maximiliano Korp 9a173f1e45 fix(core): harden Intelligence reconnect cursors 2026-07-01 11:07:07 -07:00
Maximiliano Korp c8d1c3bc53 fix: suppress duplicate wake reconnects 2026-07-01 11:07:07 -07:00
Maximiliano Korp ea0b903fb1 fix: harden passive reconnect completion gates 2026-07-01 11:07:07 -07:00
Maximiliano Korp e9df9898bd test: stabilize hitl passive replay regression 2026-07-01 11:07:06 -07:00
Maximiliano Korp ed7a1e5412 fix: isolate passive reconnect replay 2026-07-01 11:07:06 -07:00
Maximiliano Korp c606a93f44 fix: coalesce opaque thread reconnect cursors 2026-07-01 11:07:06 -07:00
Maximiliano Korp c300411619 fix: harden multidevice reconnect cursors 2026-07-01 11:07:06 -07:00
Maximiliano Korp 0fe0b4a1b2 fix: stabilize multi-device reconnect streaming 2026-07-01 11:07:06 -07:00
Maximiliano Korp 8eb9bd77cd fix: scope chat run-activity reconnects 2026-07-01 11:07:05 -07:00
Maximiliano Korp 7132026df4 fix: harden thread activity reconnects 2026-07-01 11:07:05 -07:00
Maximiliano Korp d57f9336d9 feat(react-core): reconnect native threads on run activity 2026-07-01 11:07:05 -07:00
Maximiliano Korp 2b99d96f46 test(core): guard intelligence connect completion semantics 2026-07-01 11:07:05 -07:00
Maximiliano Korp 481f67d9a8 feat(core): expose intelligence thread run activity notifications 2026-07-01 11:07:05 -07:00
Benjamin Taylor 4171319ff5 chore(vue): drop demo route from SDK PR — deferred to a follow-up
The Vue examples cannot consume the drawer until @copilotkit/web-components +
a react-core release ship AND the examples support managed Intelligence — same
constraint as the Angular vertical, which kept its demo route as a separate
follow-up PR. This PR is SDK-only (packages/vue).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:46:49 -05:00
Benjamin Taylor e109c350d3 fix(vue): register thread store with core + gate on threadEndpoints (React parity)
Ports two React-parity gaps (audit-flagged as user-facing) into the Vue
`useThreads` composable, mirroring react-core `use-threads.tsx`.

Fix A — register the thread store with core's single-slot registry:
- Adds a `watch([resolvedEnabled, resolvedAgentId])` that calls
  `copilotkit.value.registerThreadStore(agentId, store)` and, via the
  watch's `onCleanup`, `unregisterThreadStore(agentId)` on
  disable/agentId-change/unmount. Gated on `resolvedEnabled` so a disabled
  (unlicensed) store never evicts a co-mounted live store for the same agent.

Fix B — gate list + mutations on `copilotkit.threadEndpoints`:
- Derives `threadListEndpointSupported`/`threadMutationsSupported` via
  `!== false` (legacy runtimes advertise `undefined` => supported).
- Context-dispatch watcher skips dispatching (setContext(null)) when the
  list endpoint is unsupported, so no `/threads` fetch fires.
- Folds `threadEndpointsError` ("Thread endpoints are not available on this
  CopilotKit runtime") into `error` (NOT `listError`, which stays
  storeError-only) and factors `!threadEndpointsUnavailable` into
  `preConnectLoading` so the UI doesn't spin against an endpoint-less runtime.
- `guardMutation` wraps rename/archive/unarchive/delete to reject with
  "Thread mutations are not available on this CopilotKit runtime" when
  `threadEndpoints.mutations === false`, before touching the network.

Call sites:
- The shipped `CopilotThreadsDrawer` consumes `error` for its user-facing
  error banner (now surfaces the endpoints-unavailable message instead of
  spinning) and `listError` for genuine list-load failures (unchanged
  contract: storeError only, no config/runtime-setup leakage). Its `enabled`
  prop (unlicensed gate) already suppressed fetches; it now also correctly
  suppresses core-registry registration so a co-mounted live chat store for
  the same agent is not evicted. Mutation buttons (rename/archive/delete)
  reject locally on runtimes that don't serve mutations.

Item 3 (startNewThread configErrorDismissed) intentionally left out of scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:29:54 -05:00
Benjamin Taylor dc506c4c9b test(vue): cover CopilotThreadsDrawer event-routing table + guard findChatInput for SSR
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:17:33 -05:00
Mike Ryan 5bcc1d1ce0 chore: release monorepo v1.62.1 (#5791)
## Release monorepo v1.62.1

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.62.1`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.62.1`
   - Creates git tag `monorepo/v1.62.1`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.62.1
2026-07-01 10:10:06 -07:00
tylerslaton 617e88a069 chore: release monorepo v1.62.1 2026-07-01 17:07:44 +00:00
Benjamin Taylor 7803080713 fix(vue): keep setModalOpen undefined without backing modal state
Wave-4 introduced setModalOpenWithDrawerExclusion as an always-defined
function on configurationValue.setModalOpen. Under a bare
<CopilotChatConfigurationProvider> (no isModalDefaultOpen, no parent
providing modal state), this broke the pre-existing contract that
setModalOpen is undefined when the provider owns no backing modal
state — the function was defined but a no-op, since it delegated to
parentConfigValue?.setModalOpen, which was undefined.

CopilotChatToggleButton.vue depends on that undefined-ness: it checks
`config.value?.setModalOpen` and falls back to a local `fallbackOpen`
ref when absent. With the regression, clicks routed into the no-op
setter instead of the fallback, permanently stuck closed.

Fix: replace the standalone function with a `publicSetModalOpen`
computed that returns undefined when resolvedSetModalOpen (the real,
possibly-parent-inherited setter) is undefined, and otherwise wraps it
with the mobile drawer-exclusion behavior. This preserves the
undefined contract without touching resolvedIsModalOpen,
resolvedSetModalOpen, or the drawer-registration code.

Call-site enumeration for setModalOpen consumers (all read via
optional chaining, so all remain safe):
- CopilotChatToggleButton.vue: `config.value?.setModalOpen` — restored
  fallback-open behavior when the provider is bare, confirmed via new
  presence-contract tests plus the existing 5-test
  CopilotChatToggleButton.test.ts suite (all pass).
- CopilotModalHeader.vue: `config.value?.setModalOpen?.(false)` — only
  used inside modal-backed compositions (CopilotPopup/Sidebar), which
  always pass isModalDefaultOpen, so setModalOpen is always defined
  there; unaffected.
- CopilotSidebarViewInternal.vue / CopilotPopupViewInternal.vue: same
  pattern, same modal-backed guarantee; unaffected.

React's CopilotChatConfigurationProvider.tsx intentionally keeps
setModalOpen always-defined and always backed by internal state — a
different resolution than Vue's. This fix takes the minimal Vue-local
path (preserve the undefined contract CopilotChatToggleButton relies
on) rather than reworking resolvedIsModalOpen's backing, to avoid
changing bare-provider modal-open semantics.

Tests: added a "modal-setter presence contract" describe block
verifying (1) a bare provider exposes setModalOpen as undefined
(red-green verified: fails on pre-fix code, passes after), and (2) a
provider with isModalDefaultOpen exposes a working setModalOpen that
toggles isModalOpen. All 21 tests in the provider suite pass,
including the existing mobile drawer<->modal mutual-exclusion tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 12:04:56 -05:00
Tyler Slaton 018f64b2db fix(release): include web-components in monorepo scope (#5790)
## Summary
- Include `@copilotkit/web-components` in the shared `monorepo` release
scope.
- Remove the standalone `web-components` release scope from workflow
dispatch options and type definitions.
- Keep notification package counts aligned with the 16-package monorepo
scope.

## Why
`@copilotkit/web-components` should move with the rest of the shared
monorepo packages after its initial manual publish, not be released as a
separate scope.

## How
- Added `@copilotkit/web-components` to `release.config.json` under
`monorepo`.
- Removed standalone scope dropdown/options and npm URL handling.
- Verified dropdown parity, monorepo dry run, standalone-scope
rejection, and notification tests.
2026-07-01 10:02:33 -07:00