Commit Graph

12612 Commits

Author SHA1 Message Date
Maxim 03201c8ba6 feat(showcase): inspector store (React context) for timeline cards
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:40 +02:00
Maxim 5239a6ce4c feat(showcase): AG-UI event->timeline-card mapping (banking-trimmed)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:40 +02:00
Maxim f7a80553d0 feat(showcase): GlassEngine context with availability + activation gates
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:40 +02:00
Maxim a6b380691f feat(showcase): GLASS_ENGINE_AVAILABLE deployment gate helper
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:39 +02:00
Maxim 88e2d072c4 test(showcase): add vitest unit runner to banking demo
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:39 +02:00
Maxim 24cc2d3829 fix(showcase): enable Enterprise Learning so banking memory tools attach
The durable-memory demo depends on the Intelligence platform's recall_memory /
save_memory tools, which are served from `${apiUrl}/mcp` and attached to the
local BuiltInAgent run via MCP middleware ONLY when CopilotKitIntelligence is
constructed with `enableEnterpriseLearning: true` (gated in
attachIntelligenceEnterpriseLearning). The banking route never set the flag, so
in any real (non-aimock) run the memory tools never loaded: save_memory was a
no-op during teaching and recall_memory was absent, making the agent re-offer
workflow recording on every over-limit charge instead of recalling the learned
procedure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:38 +02:00
Maxim 4730301c4c fix(showcase): bump banking agent gpt-5.4-mini -> gpt-5.4 for reliable tool routing
The teach-flow's multi-step tool sequencing is the weak spot for the mini model;
the non-mini gpt-5.4 follows the recall->offer->demonstrate->save routing far
more consistently. openai/gpt-5.4 is the alias already used across the repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:38 +02:00
Maxim ec946821bb fix(showcase): offer card shows 'Recording started', not 'not recording', after Start
My collapse fix branched on isRecording, but the render closure captures a stale
isRecording (false), so clicking 'Start recording' wrongly collapsed the card to
'Okay — not recording.'. Branch on the resolved `result` instead (fresh on
complete, like the save card): onDeny resolves 'declined' -> 'not recording';
onApprove resolves the directive -> 'Recording started'. Drops the now-unused
isRecording destructure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:38 +02:00
Maxim 57fb3bd64f fix(showcase): remove conflicting over-limit routing cues + temperature 0
The 'Record a workflow?' card appeared inconsistently because two intro prompt
lines still steered the agent the wrong way on an over-limit approve — 'review
... over-limit charges -> showPendingApprovals' and 'showApprovalFlow -> explain
how an over-limit charge gets cleared' — competing with the recall->offer block.
Scope both to browse/explain only and exclude them from the approve path, and
drop the agent temperature 0.3 -> 0 so it picks the same route every time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:37 +02:00
Maxim 744f064621 fix(showcase): collapse the save + demonstrate teach cards once resolved
Same lingering-button bug as the offer card: saveLearnedWorkflow and
awaitDashboardDemonstration only special-cased status 'inProgress', so after
clicking 'Save workflow' / 'I'm done' the card kept its button (confusing —
looked like nothing happened, though the save/respond went through). Add a
status 'complete' branch that collapses each to a static line, using the HITL
render's 'result' to show saved vs discarded / finished vs cancelled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:37 +02:00
Maxim cb014feb04 fix(showcase): route over-limit approval to recall->offer, not the explainer/queue cards
On 'approve the over-limit charge' with no saved procedure, gpt-5.4-mini
sometimes called showApprovalFlow ('diagram of how to clear an over-limit
charge') or showPendingApprovals ('...including over-limit charges') instead of
recall_memory -> offerWorkflowRecording, so it never asked to record. Scope
those two tools to their real uses (explainer only when asked how it works;
queue only for reviewing pending) and explicitly exclude them from the
over-limit approve path. The approval-flow diagram stays as an informational
tool — just not a response to an approve request.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:36 +02:00
Maxim 14f4f77d2c fix(showcase): advance the record->demonstrate beat + collapse the resolved offer card
After 'Start recording', offerWorkflowRecording resolved a bare 'started', so
gpt-5.4-mini often just SAID awaitDashboardDemonstration's 'go ahead and I'll
watch' line (from its description) instead of CALLING it — leaving the offer
card frozen with the Start-recording button and a confusing text reply, even
though recording (the vignette) had begun.

- Resolve a directive result telling the agent to immediately call
  awaitDashboardDemonstration and not reply in prose (mirrors the working
  awaitDashboardDemonstration -> saveLearnedWorkflow beat).
- Collapse the offer card to a static line once resolved (status 'complete')
  so the button can't linger or be re-clicked; the live 'Recording your
  workflow' card takes over.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:36 +02:00
Maxim cad70feacc fix(showcase): lift all Radix popper overlays above the chat sidebar (z-index)
Generalizes the row-action dropdown fix: every shadcn overlay (Select,
DropdownMenu, Popover, Tooltip) portals to <body> at z-50 and renders behind
the CopilotKit chat sidebar (z-1200) when opened in-chat — the policy-code
Select in the exception form hit this too. One globals.css rule lifts every
Radix popper wrapper to z-1300 (the file's existing 'above the chat panel'
value), fixing the whole class instead of per-component patches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:35 +02:00
Maxim 592e847e4c fix(showcase): render row-action dropdown above the chat panel (z-index)
The 'More actions' menu portals to <body> at z-50, but the CopilotKit chat
sidebar is z-1200 — so the menu opened BEHIND the panel and was invisible
(clicking the three-dots appeared to do nothing). Lift this dropdown's content
to z-[1300] so it renders in front of the panel. Pairs with the earlier
pointer-events-auto fix; together the row's overflow menu works in-chat.

Verified: menu computed z-index is now 1300 vs panel 1200.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:35 +02:00
Maxim bfee2c492a fix(showcase): make in-chat pending-approvals card clickable (pointer-events-auto)
showPendingApprovals is a display-only useComponent, which CopilotKit paints
pointer-events:none on the assistant message. The table is interactive
(Approve / Deny / File policy exception 'More actions' menu), so the inherited
none made every row action unclickable in the chat. Opt the card subtree back
into pointer events.

Verified live: the 'More actions' button's computed pointer-events flips
none -> auto with the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:34 +02:00
Maxim c03c064371 feat(showcase): dev-only POST /api/v1/dev/reset to re-seed the demo store
Re-running the over-limit teach demo mutates the in-memory store (approve +
filed exception flip the charge overLimit→cleared). This endpoint re-seeds the
store in place so the $5,000 Google Ads / Marketing charge (t-1) returns to
pending/over-limit without a server restart. Gated off when NODE_ENV=production.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:34 +02:00
Maxim d033b02837 test(showcase): use confirmed @copilotkit/aimock export (LLMock) in E2E launcher
Drops the non-existent AIMock/MockServer fallback names (TS-flagged once aimock was
installed); LLMock/loadFixtureFile/validateFixtures are the real exports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:33 +02:00
Maxim cdcd5460d6 test(showcase): deterministic aimock+Playwright cross-thread memory proof (FOR-149)
AUTHORED + statically validated (playwright --list compiles spec+config, fixtures/
package JSON valid, launcher syntax OK). NOT yet green-verified — needs aimock
installed (pnpm i), the docker memory stack up, and the dev server in Intelligence
mode (multi-process; not runnable in the current sandbox). Each file carries a
'VERIFY ON FIRST GREEN RUN' checklist for the shakedown.

- e2e/memory-learning.spec.ts: seeds the procedure via REST (recall-half isolation
  per the plan), drives a fresh thread, asserts recall->unlock with no recording
  offer + the over-limit gate lifted. Save half stays HITL+LLM (drift smoke / manual).
- e2e/fixtures/memory-learning.fixtures.json: pins recall_memory -> openPolicyException
  -> finalizePolicyException -> approveTransaction.
- e2e/aimock-server.mjs: aimock launcher (programmatic, CLI fallback documented).
- playwright.config.ts: webServer array (aimock + dev in Intelligence mode, OPENAI_BASE_URL->aimock).
- package.json: +@copilotkit/aimock devDep; test:self-learning -> the spec.
- remove scripts/self-learning-smoke.mjs (dead #192 distill path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:32 +02:00
Maxim 177a68f7d4 docs(showcase): memory-based durable-learning runbook + real-LLM recall drift smoke
- README: replace dead sl-worker/knowledge/annotate Phase-C section with the
  memory runbook (docker compose one-command stack, host-TEI override for Apple
  Silicon, 715x ports, .env, cross-thread+cross-persona FOR-149 walkthrough,
  aimock E2E + drift-smoke testing notes)
- scripts/memory-drift-smoke.mjs: non-gating real-LLM tripwire that the live model
  still emits recall_memory on a fresh-thread over-limit request (save half is
  HITL-gated; covered by the manual walkthrough + aimock E2E)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:30 +02:00
Maxim 841f6db2fb feat(showcase): saveLearnedWorkflow resolves a save-triggering result (drives save_memory)
Save action now resolves a string the agent reads as status:saved + an explicit
save_memory(scope:project, kind:operational) instruction with the demonstrated
code, preserving the already-approved/don't-re-run guard. respond() takes a
string in this file, so the result is delivered as text the recall-first prompt
(Task 3) acts on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:29 +02:00
Maxim bf8a01b250 feat(showcase): recall-first over-limit handling + save learned procedure to project memory
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:27 +02:00
Maxim 66cccfb8a6 refactor(showcase): remove POC /annotate recording seam (superseded by save_memory)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:25 +02:00
Maxim 7dcb5dd4d5 feat(showcase): wire banking runtime for memory (license token + locks); full .env.example
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:24 +02:00
Maxim 42a4066d45 fix(showcase): harden banking memory stack (minio-init DNS retry, pluggable embedder, non-colliding host ports)
Surfaced while verifying Task 0 against a live stack:
- minio-init: retry mc alias set until Docker DNS resolves (idempotent bucket create)
- embedder pluggable: MEMORY_EMBEDDINGS_URL overridable + bundled tei dependency required:false
  (point at host/native TEI on RAM-constrained Apple Silicon where the emulated tei OOMs)
- deps default host ports remapped to 715x so a bare `docker compose up` coexists with a dev's Intelligence stack

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:24 +02:00
Maxim f447e1a624 feat(showcase): vendor memory-enabled Intelligence stack (cloned memory-chat recipe) for banking demo
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:33:23 +02:00
Markus Ecker 02a10800bb Merge remote-tracking branch 'origin/mme/memory-core' into mme/memory-core 2026-07-02 17:27:18 +02:00
Markus Ecker 01469359a8 merge: integrate origin/main into mme/memory-core
Resolve the single conflict in packages/web-inspector/src/index.ts by keeping
both additions: this branch's CpkMemoryList memory-tab element and main's
ɵCpkThreadDetails back-compat alias (independent top-level declarations).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 17:26:01 +02: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