mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
codex/remove-threads-cli-path
12110 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
40fb09cb77 |
feat(shell-docs): instrument framework selector with PostHog event
Fires framework_selected when a user picks a framework so the docs funnel can attribute drop-off to specific frameworks. Net-new event (no upstream equivalent in docs/). |
||
|
|
5f7974a32d |
feat(shell-docs): port Open Graph image route + vercel.json
Adds app/og/[...slug]/route.tsx for per-page social-share image generation, and a vercel.json with maxDuration: 60 on app/og/** so the Edge function has enough headroom to render OG cards. |
||
|
|
b355a9aec0 |
feat(shell-docs): port docs telemetry stack
Brings PostHog, GA4, HubSpot, Reo.dev, Scarf, and RB2B into shell-docs with parity to docs/. Adds the client-side PostHog provider with session-stitched bootstrap and pageview capture, the AnalyticsClient wrapper that mounts RB2B + GA4 hooks behind a single client boundary, the Scarf pixel for OSS attribution, and the HubSpot and Reo.dev scripts. Renames POSTHOG_PROJECT_KEY to POSTHOG_KEY across shell and shell-docs middlewares so the env names match the upstream pattern, and env-drives POSTHOG_HOST with eu.i.posthog.com as the fallback. |
||
|
|
905d742468 |
feat(react-core): auto-mounted IntelligenceIndicator + MemoizedCustomMessage memo gating signals (#4632)
## Summary Stacked on top of #4629. Two commits: 1. **MemoizedCustomMessage memo gating signals** (Friday's WIP, cleaned in CR loop). Adds three new memo gating signals to `MemoizedCustomMessage` so custom message renderers stay reactive across the structural events that affect "is this slot still authoritative?" decisions: - `numberOfMessagesInRun` — invalidates when peers stream into the same run - `isInLatestRun` — invalidates when a newer run starts - `isRunning` (gated on `isInLatestRun`) — invalidates exactly twice per run on the latest run's slots, preserving the perf-test guarantee that completed runs' messages skip re-renders during streaming `CopilotChatMessageView` consolidates per-run metadata (run-id-by-message, count-by-run, latest-run) into a single `useMemo` that runs O(n) per render rather than O(n²) per message. 2. **`IntelligenceIndicator` — auto-mounted** "Using CopilotKit Intelligence" pill, ported from the visuals of [CopilotKit/Intelligence#155](https://github.com/CopilotKit/Intelligence/pull/155). ## How the indicator works - `CopilotChatMessageView` mounts `<IntelligenceIndicator>` for every message slot whenever `copilotkit.intelligence !== undefined`. No factory, no provider, no `renderCustomMessages` registration — the caller doesn't add anything. - The indicator self-gates so only the canonical slot renders a pill: last message of the latest in-flight run, with at least one tool call whose `function.name` matches one of `DEFAULT_TOOL_PATTERNS` (currently `[/^bash$/]`, the Intelligence MCP server's canonical tool). - "Exactly one pill at any moment" is structural — only one message can ever satisfy the gates, so each renderer invocation decides independently and the result is one pill in the DOM. ### Phase machine (per-instance, all timers local) - `spinner` while `agent.isRunning` - → `check` after `agent.isRunning` falls (debounced 500 ms to absorb step-boundary `RUN_FINISHED → RUN_STARTED` blips) - → `fading` after 800 ms hold - → `hidden` after 480 ms fade animation A 200 ms `agent.isRunning` poll closes the AG-UI snapshot-subscriber gap (subscribers added INSIDE a run never see that run's `onRunFinalized`). ## API Nothing new for the user. Configure intelligence on your runtime, and the pill appears. ```tsx <CopilotKitProvider runtimeUrl="..."><CopilotChat /></CopilotKitProvider> ``` When `/info` returns `intelligence: { wsUrl: ... }`, the gate flips and the pill auto-mounts on the canonical slot. ## Configurability Tool-name matching is currently hardcoded to `[/^bash$/]`. If we need per-instance customization later (a `CopilotKitProvider` prop, or a `toolPatterns` field on `IntelligenceRuntimeInfo` so the runtime can declare its own intelligence tools), the constant becomes the fallback. ## Test plan - [x] `nx run @copilotkit/react-core:test` — **1158 passed** - [x] `nx run @copilotkit/core:test` — **424 passed** - [x] `nx run @copilotkit/web-inspector:test` — **7 passed** - [x] Build: `react-core`, `core`, `web-inspector` clean. Pill CSS bundled into `dist/v2/index.css` (10 rules + 3 keyframes). ### New test coverage - 1 walkthrough — Run A → Run B with multiple bash calls; pill follows the canonical slot through every phase. Setup passes **no `renderCustomMessages` prop** to prove auto-mount. - 4 gate tests: last-in-run / in-flight (with phase-machine fade-out) / latest-run / tool-match. - 1 intelligence gate — no pill when `copilotkit.intelligence` is undefined. - 1 explicit auto-registration assertion — pill renders solely because intelligence is set, no user setup. ## Caveats - Tool-name patterns are hardcoded; not yet configurable by the runtime or the app caller. Easy follow-up if needed. - The `CopilotChatConfigurationProvider` dependency that `CopilotChatMessageView` uses for `agentId` / `threadId` (to query state-manager) is pre-existing and not addressed here — flagged separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
b8880450b8 |
fix(docs): redirect active 404s and repair broken snippet links (#4677)
## Summary
- Repairs broken links in 4 shared snippets that were the root cause of
most internal-referrer 404s on docs.copilotkit.ai
- Adds 35 redirects in \`next.config.mjs\` covering every URL with
\`broken_link_accessed\` events from the last 30 days of PostHog data
## Approach
PostHog tracks 404s via the \`broken_link_accessed\` event (see
\`docs/POSTHOG_BROKEN_LINKS.md\`). I queried the last 30 days, grouped
by \`broken_url\`, and split the results into two buckets:
1. **Source-side bugs** — broken links coming from our own MDX. The
biggest offenders were shared snippets (\`copilot-runtime.mdx\`,
\`generative-ui/a2ui.mdx\`, \`generative-ui-specs-overview.mdx\`,
\`backend/ag-ui.mdx\`) that get inlined into many integration pages,
multiplying each broken link across the site. Fixed at source.
2. **External / legacy traffic** — search results, marketing site links,
partner sites. Added redirects.
For URLs without a clean 1:1 destination, every broken path now
redirects to the closest matching concept page (no hard 404s left). Each
ambiguous mapping was validated by reading the candidate destination's
content.
## Categories of redirects added
- \`/generative-ui/specs/*\` → \`/learn/generative-ui/specs/*\` (section
moved)
- \`/premium/{threads,inspector}\` → root equivalents (those pages are
at root, not under \`/premium\`)
- \`/built-in-agent/guides/*\` → renamed pages or section index (the
\`guides/\` prefix was dropped in the 2026-02 restructure)
- \`/learn/direct-to-llm/*\` → \`/built-in-agent\` (namespace removed)
- \`/learn/langgraph/*\` → \`/langgraph/*\` (was never under \`/learn\`)
- \`/deepagents/{prebuilt-components,custom-look-and-feel/*}\` → root
equivalents (deepagents integration is missing these pages — see
follow-up note below)
-
\`/reference/v1/hooks/{useRenderTool,useComponent,useThreads,useInterrupt,useCapabilities}\`
→ \`/reference/v2/hooks/<same>\` (these hooks are new in v2)
- \`/reference/v2/hooks/useCopilotAction\` →
\`/reference/v2/hooks/useFrontendTool\` (renamed)
- \`/whats-new/*\` → \`/learn/whats-new/*\`
- Doubled-prefix paths (\`/agent-spec/agent-spec/wayflow\`, etc.) —
straightforward un-double
- \`/zh/langgraph/deep-agents\` → \`/deepagents\` (no i18n on this site)
## Follow-up worth tracking separately
The \`integrations/deepagents/\` directory is missing several pages that
other integrations have (\`prebuilt-components.mdx\`,
\`custom-look-and-feel/\`, \`premium/\`, etc.). The redirects in this PR
band-aid the symptom; the integration page itself is incomplete vs
siblings.
## Test plan
- [x] Verified each of the 35 former-404 paths returns 308 → final 200
on local \`next dev\`
- [x] Verified rendered HTML on pages that include the fixed snippets
now emits the new link targets
- [x] Confirmed the failing pre-commit test
(\`@copilotkit/sqlite-runner:test\`) is pre-existing on \`main\` and
unrelated to this docs-only change
|
||
|
|
73c04f8b1f | Docs(Deepagents): Removed Checkpointer in Python code snippet | ||
|
|
495c331098 |
fix(docs): add redirects for active 404s on docs.copilotkit.ai
Adds 35 redirects in next.config.mjs covering every URL with
broken_link_accessed events from the last 30 days of PostHog data.
Categories:
- /generative-ui/specs/* → /learn/generative-ui/specs/* (section moved)
- /premium/{threads,inspector,premium/overview} → root equivalents
- /built-in-agent/guides/* → renamed pages or section index
- /built-in-agent/{human-in-the-loop,generative-ui/state-rendering,
cookbook/state-machine} → closest matching concept
- /learn/direct-to-llm/* → /built-in-agent (namespace removed)
- /learn/langgraph/* → /langgraph/* (was never under /learn)
- /deepagents/{prebuilt-components,custom-look-and-feel/*} →
root equivalents (deepagents integration is missing these pages)
- /guides/* with no /built-in-agent/guides equivalent → closest concept
- /reference/v1/hooks/{useRenderTool,useComponent,useThreads,
useInterrupt,useCapabilities} → /reference/v2/hooks/<same>
(these hooks are new in v2)
- /reference/v2/hooks/useCopilotAction → useFrontendTool (renamed)
- /whats-new/* → /learn/whats-new/*
- Doubled-prefix paths: /agent-spec/agent-spec/wayflow,
/langgraph/langgraph/overview, /premium/premium/overview
- /langgraph/persistence/* → /langgraph/advanced/persistence/*
- /zh/langgraph/deep-agents → /deepagents (no i18n on this site)
Verified locally: every former-404 path returns 308 → 200 final.
|
||
|
|
75abdb3a40 |
fix(docs): repair broken links in shared snippets
Several shared snippets linked to paths that no longer exist: - /generative-ui/specs/* → /learn/generative-ui/specs/* (specs moved) - /premium/threads → /threads (page is at root, not under /premium) - /premium/inspector → /inspector (page is at root, not under /premium) Because these snippets are inlined into many integration pages, each broken link multiplied across the site and accounted for the majority of internal-referrer 404s on docs.copilotkit.ai. |
||
|
|
b9ecaaaa7d |
refactor(showcase): split beautiful-chat D5 probe into per-pill family (5 pills) (#4675)
## Summary Follow-up to #4672. The aggregated multi-turn probe shipped in that PR hit a CopilotKit v2 quirk on `/demos/beautiful-chat`: only the FIRST `useComponent` tool call in a conversation paints its component. Subsequent tool calls emit (the agent's followup content arrives) but the component never mounts. Reproduced cleanly without any frontend tool involvement — pie chart turn 1 paints 5 svg circles in seconds, bar chart turn 2 emits "Bar chart rendered above…" but paints zero recharts elements. Splitting into per-pill scripts means each probe gets its own browser launch — fresh page state, fresh conversation, no `useComponent` ordering pollution. `CATALOG_TO_D5_KEY["beautiful-chat"]` maps to all five literals; `isD5Green` requires every key green for the cell to advance to D5, and per-pill failure isolation surfaces in PB row names (`d5:<slug>/beautiful-chat-pie-chart`, etc.) — a regression points directly at the broken surface in the dashboard drilldown. ## What's covered (5 pills) | Literal | Surface | Assertion | |---|---|---| | `beautiful-chat-toggle-theme` | frontend `toggleTheme` tool | `html.dark` class flip | | `beautiful-chat-pie-chart` | controlled gen-UI `pieChart` | `>= 3 svg circle` | | `beautiful-chat-bar-chart` | controlled gen-UI `barChart` | recharts container + `>= 2 .recharts-bar-rectangle` | | `beautiful-chat-search-flights` | A2UI fixed-schema FlightCards (#4668 path) | `United` / `Delta` / `$349` / `$289` literals | | `beautiful-chat-schedule-meeting` | HITL `scheduleTime` | picker mounts → click slot → "Meeting Scheduled" | All 5 verified locally end-to-end (5/5 pass, fresh page session per probe). ## What's NOT in this PR (all four documented in `_beautiful-chat-shared.ts`) - **Excalidraw Diagram** — depends on `mcp.excalidraw.com` reachability; turning D5 reliability into a third-party uptime bet is the wrong tradeoff. - **Calculator App** — sandboxed iframe makes Playwright assertions cross-frame fragile; `generateSandboxedUi` is already covered by `d5-gen-ui-open` on a different demo route, so this would be duplicate coverage. - **Sales Dashboard** — `generate_a2ui` → secondary `render_a2ui` chain renders Metric labels, but `Row`-bound PieChart / BarChart children don't paint their recharts containers when driven by aimock fixtures. Live pill click against the same fixture chain shows the inverse symptom (containers paint, Metric labels go missing). The shape suggests aimock's non-progressive arg streaming differs from a live LLM in a way the A2UI binder is sensitive to. Needs a separate aimock or binder investigation. - **Task Manager** — backend `manage_todos` dispatches and the agent emits closing content, but `StateStreamingMiddleware`'s `state.todos` propagation doesn't populate the App pane TodoList through aimock — same suspected root cause as Sales Dashboard. These four are deliberate exclusions, not deferred work. If we want to add them later, the path is clear (each gets its own `beautiful-chat-<surface>` literal + probe file + fixture + mapping entry). ## Architecture Mirrors the `_hitl-shared.ts` pattern: shared module with DOM helpers + per-pill assertions, thin individual probe files registering one `D5FeatureType` each. - `_beautiful-chat-shared.ts` — `BeautifulChatPage` extends the runner's `ConversationPage` with `click()`, with the same runtime guard as `d5-hitl-text-input.ts`. DOM helpers cast `globalThis` to a structural shape per closure (the harness's tsconfig has `types: ["node"]`, no DOM lib) — same pattern as `d5-chat-css.ts`'s `probeChatCss`. - Each fixture uses unique `d5 beautiful-chat probe: ...` substrings; the multi-stage Schedule Meeting flow uses `hasToolResult` `false → true` for round disambiguation. No `toolCallId` leakage concern since each probe runs in its own fresh page session. ## Test plan - [x] `npx nx run @copilotkit/showcase-harness:typecheck` — clean - [x] `npx nx run @copilotkit/showcase-shell-dashboard:typecheck` — no new errors (5 pre-existing test-file errors unchanged) - [x] `npx nx run @copilotkit/showcase-harness:build` — clean - [x] `OPS_BASE_URL=stub npm run build` (shell-dashboard) — clean - [x] `npm test -- --run d5-registry` — 12/12 pass with the 5 new literals (and the old `beautiful-chat` literal removed from the registry) - [x] Local end-to-end: 5/5 probes pass against the local stack via Playwright (each in its own fresh page session) |
||
|
|
fd6f7d418e |
Merge remote-tracking branch 'origin/main' into fix/showcase-d5-beautiful-chat-followup
# Conflicts: # showcase/aimock/d5-all.json |
||
|
|
ff4d7efa2a |
refactor(showcase): split beautiful-chat D5 probe into per-pill family
The aggregated multi-turn probe from #4672 hit a CopilotKit v2 quirk on /demos/beautiful-chat: only the FIRST useComponent tool call in a conversation paints its component. Subsequent tool calls emit (the agent's followup content arrives) but the component never mounts. Reproduced cleanly without any frontend tool involvement — pie-chart turn 1 paints 5 svg circles in seconds, bar-chart turn 2 emits "Bar chart rendered above..." but paints zero recharts elements. The runner can't sidestep this from inside one conversation without a page.reload() between turns, which the structural Page type doesn't expose. Splitting into per-pill scripts means each probe gets its own browser launch — fresh page state, fresh conversation, no useComponent ordering pollution. CATALOG_TO_D5_KEY maps `beautiful-chat` to all listed literals; isD5Green requires every key green for the cell to advance to D5, and per-pill failure isolation surfaces in PB row names. Coverage in this PR (5 pills): - beautiful-chat-toggle-theme (frontend tool, html.dark flip) - beautiful-chat-pie-chart (controlled gen-UI useComponent) - beautiful-chat-bar-chart (controlled gen-UI useComponent) - beautiful-chat-search-flights (A2UI fixed-schema FlightCards) - beautiful-chat-schedule-meeting (HITL with slot-click resolution) All 5 verified locally end-to-end (5/5 pass against the local stack). Out of scope, intentionally (track in follow-up): - Excalidraw — depends on mcp.excalidraw.com reachability - Calculator — sandboxed iframe; dup of d5-gen-ui-open - Sales Dashboard — generate_a2ui → render_a2ui chain renders Metric labels but Row-bound charts don't paint recharts containers under aimock fixtures (live pill against same fixture chain shows the inverse symptom). Suggests aimock's non-progressive arg streaming differs from a live LLM in a way the A2UI binder is sensitive to. Needs separate aimock/binder investigation. - Task Manager — manage_todos dispatches and agent emits closing content, but StateStreamingMiddleware's state.todos propagation doesn't populate the App pane TodoList through aimock — same suspected root cause as Sales Dashboard. Architecture details: - _beautiful-chat-shared.ts factors DOM helpers + per-pill assertions, mirroring _hitl-shared.ts's pattern for an extended Page type with click() + a runtime guard - Each fixture uses unique D5-prefixed userMessage substrings; the multi-stage Schedule Meeting flow uses hasToolResult false→true for round disambiguation (no toolCallId leakage since each probe runs in its own fresh page session) |
||
|
|
e3b696c29d |
feat(showcase-finance-erp): animate chat tool cards on mount (#4631)
## Summary Replace the abrupt "cut in" with a 300ms fade + slide-from-bottom entrance on each chat card so they feel connected to the streaming response instead of popping in. Follow-up polish on [#4587](https://github.com/CopilotKit/CopilotKit/pull/4587). ## What changed Added `animate-in fade-in slide-in-from-bottom-2 duration-300 ease-out` to the root element of every tool render surface in the chat: - `ToolCard` — `SpecializedToolCard` and `DefaultToolCard` (covers `do_research`, `do_projections`, `navigate_and_filter`, dashboard ops, `render_chat_visual`, etc.) - `InlineChart` (both placeholder and rendered chart) - `CashPositionCard` (both placeholder and full card) - `InventoryReorderCard` (both placeholder and full card) - `InvoiceApprovalCard` (both placeholder and full card) ## Why this approach - **`tw-animate-css` is already imported** in `examples/showcases/deep-agents-finance-erp/src/app/globals.css` — no new dependencies. - **Mount-time CSS animation, not Framer Motion** — the cards are short-lived per turn and don't need orchestration; CSS keyframes resolve to `animation-name: enter` exactly once on first paint and don't re-fire on prop transitions, so swapping between `InProgress` and the populated state stays smooth. - 300ms `ease-out` matches the rest of the demo's transition timing. ## Test plan - [x] Chat → "Cash Position" → cards slide+fade in (verified via `getComputedStyle().animationName === "enter"`, `animationDuration === "0.3s"`). - [x] Same animation fires for `do_research` / `do_projections` tool cards, inline charts, approval cards, and inventory reorder cards. - [x] No layout shift or jank in successive turns. - [ ] Reviewer: visual verification on a non-mac browser if possible (animation runs on standard CSS, but worth confirming). ## Notes - No JS/runtime changes. Pure CSS class additions via Tailwind utilities. - Decoupled from the HITL fix in [#4630](https://github.com/CopilotKit/CopilotKit/pull/4630) — landing this independently is fine. |
||
|
|
b460564b7d |
fix(showcase-finance-erp): wire request_approval HITL through useInterrupt (#4630)
## Summary The Approve / Reject card in the finance-erp showcase never worked end-to-end — the card flashed in then vanished and the agent run finished with the LangGraph checkpoint left in a half-paused state. This was a pre-existing bug, not introduced by [#4587](https://github.com/CopilotKit/CopilotKit/pull/4587). ## Why The agent's `request_approval` tool calls `copilotkit_interrupt(action="request_approval", args={...})` which raises a `GraphInterrupt`. LangGraph pauses the run, stores the interrupt on the checkpoint, and `ag_ui_langgraph` emits a `CUSTOM` event with `name: "on_interrupt"` carrying the approval payload. Then the run finalizes (`RUN_FINISHED`). The frontend was using `useHumanInTheLoop`, which is the V2 hook for **frontend-executed** tools (LLM calls a tool, frontend resolves a Promise — no agent-side execution). It does not subscribe to `on_interrupt` events at all, so: - The render registered for `request_approval` saw only the streamed tool call from `MESSAGES_SNAPSHOT` and rendered with `status: InProgress` (no `executingToolCallIds` entry was ever set). - The agent's checkpoint had a pending interrupt that no UI was offering to resolve. V2 ships a separate `useInterrupt` hook specifically for LangGraph-style interrupts. Switching to it fixes the round trip. ## What changed - `src/hooks/use-request-approval.tsx` — replaced `useHumanInTheLoop` with `useInterrupt` and bridged the result to the existing `InvoiceApprovalCard` / `InventoryReorderCard` components (no card markup changes). The `respond` callback the cards expect is now backed by `resolve` from `useInterrupt`, which sends `forwardedProps.command.resume` back to the agent. - Added a no-op `useRenderTool({ name: "request_approval", render: () => null })` so the existing wildcard `useRenderTool({ name: "*" })` in `shell.tsx` doesn't render a stale generic ToolCard alongside the interrupt UI. - JSON-parse `event.value` — the runtime delivers the interrupt payload as a JSON-encoded **string** (the structured object lives under `rawEvent.value`). Accessing properties directly silently returns `undefined` and filters the interrupt out, which is what masked an earlier iteration of this fix. ## Test plan - [x] Click "Approve Payments" → agent runs do_research, then surfaces the InvoiceApprovalCard with the overdue invoices and Approve / Reject buttons - [x] Click "Approve Payment" → agent log: `[HITL] request_approval RESUMED answer='{"approved": true, "message": "Payment approved for 3 invoice(s) totaling $153,500.00"}'`. Run continues with the user response. - [x] Click "Reject" → resume command carries `{approved: false}`; agent acknowledges and stops processing. - [x] Click "Reorder Inventory" → same flow surfaces `InventoryReorderCard` with Approve PO / Skip Reorder buttons (the hook handles both `type` values). - [ ] Reviewer: please verify against your own LangGraph showcase setup that no other HITL flow regressed. ## Notes - No package changes. `@copilotkit/react-core` already exports `useInterrupt` from V2. - The fix is contained to a single file (`use-request-approval.tsx`); the cards themselves are untouched. |
||
|
|
48cd3b2c93 |
feat(showcase/voice): D5 mapping + sample-button bypasses /transcribe (#4674)
## Summary - **Dashboard mapping fix.** `CATALOG_TO_D5_KEY` in `showcase/shell-dashboard/src/lib/live-status.ts` was missing `voice → ["voice"]`, so `computeMaxPossible` capped the langgraph-python voice cell at D4 even when the d5-voice probe row was green. The harness `REGISTRY_TO_D5` already had the entry; only the dashboard mirror was out of sync. - **Sample-button decoupled from `/transcribe`.** The "Play sample" button used to fetch `sample.wav` and POST it to the runtime's transcription endpoint, which made the sample button and the mic indistinguishable under aimock (both returned the canned transcription). Reworked it into a synchronous static-text injector — sample button is now a deterministic test/demo affordance, and the mic is the only path that exercises real Whisper transcription. Synced across all 18 voice-enabled integrations. Phrase stays `"What is the weather in Tokyo?"` so aimock's `weather in Tokyo` substring fixture still matches. - **Probe-test parity.** Added the missing `d5-voice.test.ts` companion (every other `d5-*.ts` script has one) — 9 tests covering registration, `buildTurns`, `preFill` (sample-button click + textarea-poll path), and the weather/Tokyo assertion. - **QA + e2e cleanup** for langgraph-python: dropped the no-longer-applicable "Transcribing…" mid-flight assertion and the `block /demo-audio/sample.wav` error-state subsection. Other 16 integrations' qa/e2e files follow in a parity sync PR. ## Test plan - [x] `nx test @copilotkit/showcase-harness -- --run d5-voice` → 9/9 pass - [x] `npm test` in `showcase/shell-dashboard` → 509/510 pass (1 skipped, 0 failed) - [x] `nx build @copilotkit/showcase-harness` → clean - [x] Local boot: `langgraph-cli dev` (port 8123) + `next dev` (port 3000) + dashboard (port 3002) — voice page at `/demos/voice` renders, "Play sample" injects the canned phrase instantly, send → agent returns weather, mic → real Whisper transcription with `OPENAI_API_KEY` set - [ ] Reviewer: confirm the langgraph-python voice cell on the live dashboard advances to D5 once the next d5-voice probe tick lands a green row |
||
|
|
bde2286c88 | Merge branch 'main' into fix/finance-erp-hitl-interrupt | ||
|
|
8b11e52d8e | Merge branch 'main' into feat/finance-erp-chat-animations | ||
|
|
9e93f951e5 | style: auto-fix formatting | ||
|
|
728ed61ce8 |
feat(showcase/voice): D5 mapping + sample-button bypasses /transcribe
The langgraph-python voice cell sat at D4 even when its d5-voice probe row was green. Root cause: the dashboard's CATALOG_TO_D5_KEY mirror in showcase/shell-dashboard/src/lib/live-status.ts was missing voice -> ["voice"], so computeMaxPossible capped voice at D4 regardless of probe state. The harness REGISTRY_TO_D5 already had the entry; only the dashboard mirror was out of sync. Separately, the "Play sample" button used to fetch sample.wav and POST it to /transcribe. With aimock that meant both the sample button AND the mic returned the same canned response, which made it impossible to demo the mic path locally without conflating the two affordances. Reworked the button into a synchronous static-text injector (onTranscribed(sampleText)) so: - Sample button = deterministic test/demo affordance, no runtime calls. - Mic = real Whisper transcription via /transcribe. Synced across all 18 voice-enabled integrations. Phrase stays "What is the weather in Tokyo?" so aimock's "weather in Tokyo" substring fixture still matches. Also adds the missing d5-voice.test.ts companion (every other d5-* probe script has one) and trims the langgraph-python qa/voice.md + e2e steps that depended on the now-removed async behavior. |
||
|
|
f9393f6083 |
feat(shell-docs): port OpsPlatformCTA, place sign-up CTAs, rebrand to Enterprise Intelligence Platform (#4670)
## Summary Brings the docs→dashboard sign-up funnel to shell-docs and pulls the threads documentation stack into parity with upstream. Mirrors PRs [#4592](https://github.com/CopilotKit/CopilotKit/pull/4592) (Wave 1, 30+ placements), [#4642](https://github.com/CopilotKit/CopilotKit/pull/4642) (rebrand + threads restoration), and follow-up commit `0ada76b9a` (CTAs on threads pages). Lands in four commits: 1. **Port the `OpsPlatformCTA` component** to `showcase/shell-docs/src/components/react/ops-platform-cta.tsx` and wire it into the shared MDX registry. 2. **Place 22 `<OpsPlatformCTA>` instances** across shell-docs MDX pages with stable surface identifiers that match upstream's, so PostHog click attribution stays continuous across the docs.copilotkit.ai cutover. 3. **Rebrand "CopilotKit platform" → "Enterprise Intelligence Platform"** in shell-docs prose, mirroring the docs/ rebrand. 4. **Add useThreads at the canonical reference path** + threads-stack content parity (see "Threads parity" below). ## Adaptations from upstream - **Visual tokens** — swapped indigo/purple Tailwind utilities for `--accent` / `--violet-light` / `--border` / `--text*` CSS variables already used by the rest of shell-docs. - **No dark mode** — dropped `dark:` modifiers; shell-docs has no dark theme yet. - **No lucide-react** — inlined `ArrowRight`, `Info`, and `Sparkles` as SVG components. - **No client-side PostHog** — shell-docs ships server-side PostHog (middleware) only and has no `posthog-js`. UTM params on the dashboard URL (`utm_source=docs`, `utm_medium=cta`, `utm_campaign=intelligence`, `utm_content={surface}`) are the source of truth for click attribution. - **Inline-style overrides** — `text-decoration: none` on the card/tile wrappers and explicit `color` on the inline-button text and info-link to defeat shell-docs's `.reference-content a` rule. ## Placement coverage 22 placements: 18 direct ports of upstream surfaces, 3 path-adjusted, and 1 structural. **Direct (18):** `inspector`, `shared-state`, `threads`, `troubleshooting/event-inspector`; integration quickstarts for `a2a`, `ag2`, `agent-spec`, `built-in-agent` (overview + quickstart), `crewai-flows`, `deepagents`; `langgraph/prebuilt-components`; the four shared snippets (`basics/prebuilt-components`, `premium/headless-ui`, `premium/observability`, `premium/overview`); the shared `threads/threads` snippet; the canonical `reference/hooks/useThreads`. **Path-adjusted (3):** `learn/intelligence-platform` → `premium/intelligence-platform`; `learn/threads` → `premium/threads-explained`; `learn/tutorials/multi-conversation-chat` → `tutorials/multi-conversation-chat`. **Structural (1):** root `prebuilt-components.mdx` → `prebuilt-components/index.mdx`. **Skipped:** `quickstart.mdx` (root, routing shim), `(root)/index.mdx` (no MDX docs landing), per-framework integration `index.mdx` files (no FrameworkOverview equivalent), `reference/v2/components/{CopilotChat,CopilotKit}.mdx` and `reference/v2/index.mdx` (different layout). ## Routing note A few placement targets are MDX files that shell-docs doesn't currently expose at a public URL — they're orphans pending a registered framework slug. Specifically: `agent-spec/quickstart.mdx`, `deepagents/quickstart.mdx`, `a2a/quickstart.mdx`. Mirroring the upstream placement here is defensive; tracked as part of the broader IA gap work in PDX-84. ## Rebrand sweep 11 files updated, 50 occurrences collapsed into the canonical name. Patterns: `CopilotKit platform` → `Enterprise Intelligence Platform`; `CopilotKit Intelligence Platform` → `Enterprise Intelligence Platform`; `Intelligence Platform` (standalone) → `Enterprise Intelligence Platform`. Also fixes two `a Enterprise` → `an Enterprise` article typos. URL slugs (`/learn/intelligence-platform`, `/premium/intelligence-platform`) intentionally untouched. ## Threads parity The previous version of shell-docs had `useThreads.mdx` at `src/content/docs/reference/v2/hooks/useThreads.mdx`, but the canonical reference renderer reads from `src/content/reference/`, not `src/content/docs/reference/`. Result: `/reference/hooks/useThreads` 404'd while upstream's docs had a working useThreads page for weeks. This PR moves useThreads to the canonical path so it resolves, and pulls the rest of the threads stack into content parity with upstream: - `OpsPlatformCTA` added to the reference page's component map so hook reference pages can host sign-up CTAs (used here on useThreads itself). - useThreads recreated at `src/content/reference/hooks/useThreads.mdx`. Drops the `<ThreadsEarlyAccess>` wrapper (canonical reference dir doesn't use it — threads is GA) and the `doc_type` frontmatter field (canonical hooks use plain `title` + `description` only). Keeps the local `lastRunAt` PropertyReference (deliberately preserved per commit `9f18b50f0`) and the new CTA placement. - Cross-links to useThreads in `threads.mdx` and the shared snippet repointed at `/reference/hooks/useThreads` (canonical) instead of `/reference/v2/hooks/useThreads` (404). - Prerequisite version bumped from `@copilotkit/react-core v1.50+` to `v1.56+` in `threads.mdx` and the shared snippet, matching upstream. Page-structure differences from upstream are preserved per shell-docs IA: `learn/threads` stays `premium/threads-explained`, `learn/intelligence-platform` stays `premium/intelligence-platform`, `learn/tutorials/...` stays `tutorials/...`. ## Test plan - [ ] `/inspector`, `/threads`, `/shared-state`, `/troubleshooting/event-inspector` render the inline CTA above the page content - [ ] `/built-in-agent`, `/built-in-agent/quickstart`, `/ag2/quickstart`, `/crewai-crews/quickstart` render the card CTA above the prerequisites/video, with no underlines on the title/body and white button text on the violet button - [ ] `/langgraph-python/prebuilt-components` renders the inline CTA above the IframeSwitcher - [ ] `/premium/intelligence-platform` and `/premium/threads-explained` render their CTAs between the intro paragraph and the first concept section - [ ] `/tutorials/multi-conversation-chat` renders its CTA inside the early-access wrapper - [ ] `/prebuilt-components` renders the inline CTA above "Pre-built components for agentic chat" - [ ] `/reference/hooks/useThreads` resolves (no 404) and renders the card CTA above "## Overview", with the `lastRunAt` PropertyReference still present in the Return Value section - [ ] CTA buttons all link to `dashboard.operations.copilotkit.ai/?utm_source=docs&utm_medium=cta&utm_campaign=intelligence&utm_content={surface}` with the correct surface ID - [ ] Pages that mention the platform brand consistently say "Enterprise Intelligence Platform" — no remaining "CopilotKit platform" / "CopilotKit Intelligence Platform" / bare "Intelligence Platform" - [ ] `/threads` "Next steps" → "API reference" link goes to the working `/reference/hooks/useThreads` (not the 404 `/reference/v2/hooks/useThreads`) |
||
|
|
a83acc7fb8 |
fix(react-core): IntelligenceIndicator matches the renamed copilotkit_knowledge_base_shell tool
The Intelligence platform's MCP tool was renamed from `bash` to `copilotkit_knowledge_base_shell` (intelligence/mme/integrate-sl 4256c13). Update the indicator's `DEFAULT_TOOL_PATTERNS` to match the new name so the pill keeps rendering on the right assistant slots. Test fixtures that previously used the bare `bash` name follow the rename — both the default in `emitAssistantMessageWithToolCalls` and the explicit `tc_match` entry in the tool-match condition test. |
||
|
|
a86076f76b |
feat(showcase): D5 probes for headless-simple + headless-complete (langgraph-python) (#4673)
## Summary - **Promotes `/demos/headless-complete` to its own D5 feature type** (`gen-ui-headless-complete`) so the dashboard cell can reach D5. Previously `headless-complete` aliased onto `gen-ui-headless`, which navigated to `/demos/headless-simple` and asserted on a `show_card` tool the headless-complete page doesn't even register — i.e. the cell was never actually being probed. - **Extends `gen-ui-headless`** (the simple probe) to also click the "Largest continent" chip and assert the canonical Asia text reply. - **Both probes now click chips via `preFill`** instead of typing the prompt — same handler the user clicks, no input drift. - **Bug fixes uncovered while wiring this up locally** that explain why the dashboard matrix had been showing every cell as D0 — see "What was actually broken" below. ## What was added (the feature work) - New `gen-ui-headless-complete` D5 feature type + script that exercises **all 5 chips** on `/demos/headless-complete`: - `Weather in Tokyo` → `WeatherCard` (per-tool `useRenderTool`) - `AAPL stock price` → `StockCard` (per-tool `useRenderTool`) - `Highlight a note` → `HighlightNote` (frontend `useComponent`) - `Sketch a diagram` → best-effort assistant response (Excalidraw MCP path) - `Largest continent` → "Asia is the largest continent…" text reply - New fixture `harness/fixtures/d5/gen-ui-headless-complete.json` (also bundled into `aimock/d5-all.json`) for AAPL + highlight + Excalidraw prompts. - `headless-complete` `UserBubble` + `AssistantBubble` now carry `data-message-role` so the harness conversation runner can detect message arrivals (mirrors the headless-simple convention; required to probe the page at all). - Mappings updated in lockstep: `REGISTRY_TO_D5` (harness) and `CATALOG_TO_D5_KEY` (dashboard) both map `headless-complete → ["gen-ui-headless-complete"]`. ### Non-obvious fixture detail worth flagging Aimock's `toolCallId` matcher reads only the **last** tool message in the request, but in a multi-turn probe the "last tool" stays on a previous turn's id until a new tool runs. A bare `toolCallId` narration fixture will therefore fire for the *next* turn's prompt and hijack it with a stale narration. The fix is to pin each narration fixture with both `userMessage` AND `toolCallId`, and order them BEFORE the bare `userMessage` toolCall fixture in the array — that way the more-specific narration only fires on the matching turn's second leg, and the bare userMessage fixture covers the first leg. ## What was actually broken (incidental bugs fixed) These were uncovered while running the new probe locally — none of them were caused by this PR, all of them prevented the dashboard from working at all in `--live` mode. Each is a separate commit so they can be reviewed / cherry-picked independently: 1. **`fix(showcase/harness): wire pbWriter into ProbeContext for live writes`** — `runner.ts` constructed `ctx` without `writer`, so every per-feature side row from every driver (e2e-deep's `d5:<slug>/<featureType>`, liveness's `health:<slug>` / `agent:<slug>`, etc.) was silently dropped on `--live` runs. Only aggregate primary results made it to PB. This is why the dashboard matrix showed every cell as D0 even after a successful `--live` probe. 2. **`fix(showcase/harness): align CLI smoke input slug shape with discovery`** — `buildSmokeInputs` passed `name: manifest.name` (display name like "LangGraph (Python)") which the liveness driver's `deriveSlug` used as the slug, producing rows like `health:LangGraph (Python)` that didn't join with anything else. Matches production discovery shape (`name = showcase-<slug>`) now. 3. **`fix(showcase/harness): use PB-validator-compliant email for local superuser`** — PocketBase 0.22 rejects `admin@localhost` (single-label TLD). Switched the hardcoded local creds to `admin@localhost.dev`. 4. **`chore(showcase/dashboard): plumb NEXT_PUBLIC_* build args in local compose`** — `NEXT_PUBLIC_POCKETBASE_URL` and `NEXT_PUBLIC_SHELL_URL` were unset at build time, so the dashboard JS couldn't reach PB from the browser at all (FATAL-CONFIG banner) and every Demo/Code link in the matrix rendered as `about:blank#shell-url-missing`. ## Verification Run locally against the langgraph-python integration: ```sh docker compose -f showcase/docker-compose.local.yml up -d aimock pocketbase docker exec showcase-pocketbase /usr/local/bin/pocketbase migrate up --dir=/pb_data docker exec showcase-pocketbase /usr/local/bin/pocketbase admin create admin@localhost.dev showcase-local-dev --dir=/pb_data docker compose -f showcase/docker-compose.local.yml up -d --build dashboard langgraph-python npx tsx showcase/harness/src/cli.ts test langgraph-python --d5 --verbose # 33/33 passed, including gen-ui-headless and gen-ui-headless-complete npx tsx showcase/harness/src/cli.ts test langgraph-python --level all --live # Writes the full ladder to PB ``` Open http://localhost:3200 — the langgraph-python `headless-simple` and `headless-complete` cells both show **D5** with API ✓ / RT ✓ / CV ✓. ## Test plan - [ ] Run `npx tsx showcase/harness/src/cli.ts test langgraph-python --d5 --verbose` and confirm `gen-ui-headless` and `gen-ui-headless-complete` both green. - [ ] Run with `--live` and confirm `d5:langgraph-python/gen-ui-headless-complete` appears in PocketBase as `green`. - [ ] Open the dashboard matrix and confirm the langgraph-python `headless-complete` cell shows D5/D5. - [ ] Visually click each chip on `/demos/headless-complete` and confirm the right surface renders (WeatherCard / StockCard / HighlightNote / Excalidraw / Asia text). - [ ] D5 probe still passes for every other langgraph-python feature (no regressions in the existing 32 features). ## What was NOT done - The `data-message-role` bubble tags are only on the **langgraph-python** copy of `headless-complete/{user,assistant}-bubble.tsx`. The other 16 integrations' headless-complete demos still lack the attribute. They aren't probed at D5 today, so this is fine — but propagate before bumping any of them to D5. - The local CLI's `--smoke / --d4 / --d5 / --level all` flag set does not run the `e2e-demos` driver that emits `e2e:<slug>/<featureId>` rows, so the depth ladder caps at D2 from those flags alone. Dashboard verification in this PR populated D3 rows manually. Wiring `e2e-demos` (or an equivalent D3 generator) into the local CLI is a separate follow-up. |
||
|
|
53d7999c05 |
Merge remote-tracking branch 'origin/main' into feat/showcase-d5-headless-chat
# Conflicts: # showcase/aimock/d5-all.json |
||
|
|
6b2bdbcfa9 |
chore(showcase/dashboard): plumb NEXT_PUBLIC_* build args in local compose
The dashboard image was being built with only `OPS_BASE_URL` set; the two other compile-time env vars used by the matrix view stayed unset: - NEXT_PUBLIC_POCKETBASE_URL — left at the dev fallback in production builds, which surfaces a "FATAL-CONFIG: NEXT_PUBLIC_POCKETBASE_URL was unset at build time" banner in the browser console and causes the matrix's PB SSE subscription to fail (no live updates). - NEXT_PUBLIC_SHELL_URL — left unset, so every Demo / Code link in the matrix renders as `about:blank#shell-url-missing`. Pin both at build time: - POCKETBASE_URL → http://localhost:8090 (host port the user's browser reaches; container-internal `pocketbase:8090` is unresolvable from outside the compose network). - SHELL_URL → http://localhost:3100 (langgraph-python integration host port; no shared "shell" service in the local stack). |
||
|
|
5034e83054 |
fix(showcase/harness): use PB-validator-compliant email for local superuser
PocketBase 0.22's email validator rejects `admin@localhost` (single- label TLD) with `validation_is_email: Must be a valid email address`, breaking PB auth from the harness CLI on a fresh local stack — `pb-write-failed` / `pb-auth failed: 400` on every --live run. Switch the hardcoded local creds to `admin@localhost.dev`. The matching superuser must be created with the running server's data directory pinned: `pocketbase admin create admin@localhost.dev showcase-local-dev --dir=/pb_data` (the create command's default `./pb_data` differs from the server's `--dir=/pb_data`, so the record otherwise lands in a different SQLite file and the running server can't see it). |
||
|
|
e5c68c02ee |
fix(showcase/harness): align CLI smoke input slug shape with discovery
`buildSmokeInputs` was passing `name: manifest.name` (the display name, e.g. "LangGraph (Python)") which the liveness driver's `deriveSlug` stripped of a leading `showcase-` prefix and used as the slug — producing rows like `health:LangGraph (Python)` and `agent:LangGraph (Python)` that didn't join with anything else on the dashboard's depth ladder. Production discovery sets `name` to the Railway service name (`showcase-<slug>`), which strips cleanly to the slug. Mirror that shape from the local CLI so all rows for a service share the same keyspace and the dashboard cell can advance past D0. |
||
|
|
85afa8ee9e |
fix(showcase/harness): wire pbWriter into ProbeContext for live writes
The CLI's runner.ts created a `pbWriter` when --live was passed but never plumbed it into `ctx.writer`, so every per-feature side row from every driver (e2e-deep's `d5:<slug>/<featureType>`, liveness's `health:<slug>` / `agent:<slug>`, etc.) was silently dropped. Only the aggregate primary results made it to PocketBase, which is why the dashboard matrix showed every cell as D0 even after a successful --live probe run. Now `ctx.writer = pbWriter` when --live is on; without --live the field is omitted, matching the legacy "no side emission" behavior. |
||
|
|
3eb53a8621 |
feat(showcase): D5 probe for headless-complete + extend headless-simple (langgraph-python)
Promotes /demos/headless-complete to its own D5 feature type so the
dashboard cell can reach D5 instead of riding on the headless-simple
probe (which was navigating to /demos/headless-simple regardless of
which catalog feature triggered it).
- New gen-ui-headless-complete D5 feature type + script that clicks
each suggestion chip via preFill and asserts the right surface
renders: WeatherCard (get_weather), StockCard (get_stock_price),
HighlightNote (frontend useComponent), Excalidraw best-effort, and
the canonical "Asia is the largest continent" text reply.
- Existing gen-ui-headless script now drives both turns by chip
click (Profile card + Largest continent) instead of typing.
- Fixtures pin narration legs with both userMessage AND toolCallId
and order them before the bare userMessage toolCall fixture —
aimock's toolCallId matcher reads the LAST tool message in the
request, but in a multi-turn probe that "last tool" stays on a
previous turn's id until a new tool runs, which would otherwise
hijack a later turn's prompt with a stale narration.
- headless-complete UserBubble + AssistantBubble now carry
data-message-role so the harness conversation runner can detect
message arrivals (mirrors the headless-simple convention).
- Mappings updated in lockstep:
- REGISTRY_TO_D5: headless-complete -> ["gen-ui-headless-complete"]
- CATALOG_TO_D5_KEY (dashboard): same.
|
||
|
|
faa2a556d0 |
test(runtime): cover Intelligence MCP auto-attach via forwardedProps
Four cases at the agent layer (BuiltInAgent reading forwardedProps):
* attaches when `copilotkitIntelligence` carries all three strings
(userId, apiKey, mcpUrl) — outbound headers carry Authorization +
X-Cpki-User-Id.
* does NOT attach when the bag is absent (no Intelligence wiring on
this run).
* does NOT attach when the bag is partial (e.g. mcpUrl missing).
* does NOT attach when the user has already configured an MCP server
pointing at the same URL — explicit user config wins, with the
user's headers and resolver hitting the wire.
|
||
|
|
a46acc3f94 |
feat(runtime/agent): auto-attach Intelligence MCP server via input.forwardedProps
Runtime side (intelligence/run.ts): when `runtime.intelligence.mcpServer` is enabled, build a `copilotkitIntelligence` bag carrying the resolved user-id, project apiKey, and the platform MCP URL, and pass it through on `RunAgentInput.forwardedProps` to the agent. Skipped when the flag is off — runs that don't go through this Intelligence path simply don't see the bag. Agent side (BuiltInAgent's run code): if `forwardedProps.copilotkitIntelligence` contains all three string values AND the user's static `config.mcpServers` doesn't already include the same URL, append a per-request `MCPClientConfigHTTP`. Its `options.fetch` closes over apiKey + userId and stamps `Authorization: Bearer <apiKey>` and `X-Cpki-User-Id: <userId>` on every outbound MCP call. The custom fetch is the MCP TypeScript SDK's documented extension point for per-request header injection — no extra wrapper class, no separate framework concept. The agent class is otherwise untouched: no new fields, no per-request side channels, no typed reference to `CopilotKitIntelligence`. Other agents that don't read `forwardedProps.copilotkitIntelligence` ignore the bag. Pulls in the AI SDK's stable `createMCPClient` export (rename from `experimental_createMCPClient`) — the experimental name was deprecated; `mcp-clients.test.ts`'s mock setup follows. |
||
|
|
1de2fae369 |
feat(runtime): CopilotKitIntelligence.mcpServer opt-in flag + ɵ-accessors
Adds `mcpServer?: boolean` to `CopilotKitIntelligenceConfig` (default `false`). When true, the runtime emits the per-request bag the agent needs to attach the platform's MCP server. Internal accessors `ɵisMcpServerEnabled()` and `ɵgetApiKey()` round out the existing `ɵgetApiUrl()`. Used by the runtime layer in the forthcoming auto-attach commit; not part of the public surface. |
||
|
|
44cb538856 |
feat(runtime/v2): re-export MCPClient and MCPTransport from @ai-sdk/mcp
Convenience re-exports so consumers wiring custom MCP clients (via `mcpClients`) or custom transports don't need to add `@ai-sdk/mcp` to their dependencies just to type the values. |
||
|
|
04e9e969e6 |
feat(showcase): D5 probe for beautiful-chat (langgraph-python) (#4672)
## Summary - Add a dedicated D5 conversation probe for `beautiful-chat` so the cell can advance past D4 in the dashboard. Asserts the A2UI fixed-schema FlightCard surface renders with stable text fingerprints (`United Airlines`, `Delta`, `$349`, `$289`) from the `search_flights` tool round-trip — the same render path that PR #4668 fixed. - Replace the freeloading `["agentic-chat"]` alias in `REGISTRY_TO_D5` with a dedicated `["beautiful-chat"]` key, and re-add the matching `CATALOG_TO_D5_KEY` entry so `computeMaxPossible` lifts the D4 cap to D5. Commit `974494ecb` had stripped the alias because it would inherit agentic-chat's green status without exercising any A2UI assertion; this PR replaces it with a real probe instead of restoring the alias. - Splice the new fixture (two entries, `hasToolResult` false→true mirroring the `gen-ui-headless` pattern) into `showcase/aimock/d5-all.json`. ## What changed - `showcase/harness/src/probes/scripts/d5-beautiful-chat.ts` — new probe. Single turn: navigates `/demos/beautiful-chat`, sends the unique substring `d5 beautiful-chat probe: search flights from SFO to JFK`, asserts FlightCard literals appear (60s budget on first card, 5s on siblings). - `showcase/harness/fixtures/d5/beautiful-chat.json` — new fixture. Payload mirrors `call_fp_search_flights_001` from `feature-parity.json` so visual fingerprints match across both runners. - `showcase/harness/src/probes/helpers/d5-registry.ts` — add `"beautiful-chat"` to the `D5FeatureType` union + runtime mirror. - `showcase/harness/src/probes/helpers/d5-feature-mapping.ts:111` — point at the new probe key, not the agentic-chat alias. - `showcase/shell-dashboard/src/lib/live-status.ts` — re-add `"beautiful-chat": ["beautiful-chat"]` to `CATALOG_TO_D5_KEY`. - `showcase/aimock/d5-all.json` — splice the two new fixture entries (additions only). ## Why one surface, not all 5 pills The probe asserts only the Search Flights pill. Lowest-risk surface to start with: literal-text fingerprints (no LLM-output dependency), single-turn `search_flights` call, fastest round-trip among the A2UI pills. Sales Dashboard's `generate_a2ui` is a two-stage flow (secondary LLM bound to `render_a2ui`) that takes 90s+ on cold starts and would balloon the probe budget. Once this lands and runs green, it's straightforward to add surface-specific D5 literals (`beautiful-chat-flights`, `beautiful-chat-dashboard`, etc.) — the registry is set up for it and `isD5Green` uses `every` so multi-key gating just works. ## Test plan - [x] `npx nx run @copilotkit/showcase-harness:typecheck` — clean - [x] `npx nx run @copilotkit/showcase-shell-dashboard:typecheck` — no new errors (5 pre-existing test-file errors unchanged) - [x] `npm test -- --run d5-registry` (harness) — 12/12 pass with the new literal - [x] `npm test -- --run depth-utils` (shell-dashboard) — 35/35 pass - [x] `npm run build` (harness) — clean - [x] `OPS_BASE_URL=stub npm run build` (shell-dashboard) — clean - [x] Local end-to-end: aimock + pocketbase + dashboard up, full D1–D5 ladder seeded into PB, dashboard renders `beautiful-chat × langgraph-python` cell as **D5**. Beautiful Chat demo at `localhost:3100/demos/beautiful-chat` round-trips the new fixture. ## Follow-up (not in this PR) - The full harness orchestrator running this probe end-to-end was not exercised locally — verifying it in the Railway deploy is the proper end-to-end test. The static side (mapping + registry + chip render) is verified locally via the seeded PB row. - A vitest unit test for `d5-beautiful-chat.ts` (similar shape to `d5-chat-slots.test.ts`) is a reasonable next addition. The other LGP-wave probes in `harness/src/probes/scripts/` mostly don't ship paired tests, so this PR follows the existing pattern. |
||
|
|
653abdb901 |
feat(showcase): expand beautiful-chat D5 probe to 7 of 9 pills
Builds on the initial Search Flights-only probe by extending to a multi-turn ConversationTurn[] that asserts surface-specific render fingerprints for 7 of the 9 pills in /demos/beautiful-chat. Pills covered (turn order is load-bearing — see script jsdoc): 1. Toggle Theme — html.dark class flip (toggleTheme frontend tool) 2. Pie Chart — >= 3 svg circles (pieChart useComponent) 3. Bar Chart — recharts container + >= 2 bar rectangles 4. Search Flights — A2UI FlightCard literal fingerprints (#4668 path) 5. Schedule Meeting — MeetingTimePicker mounts; assertion CLICKS a slot to resolve the HITL pause before subsequent turns 6. Sales Dashboard — A2UI dynamic generate_a2ui → secondary render_a2ui; "Total Revenue" + recharts container (90s budget) 7. Task Manager — enableAppMode + manage_todos; "To Do" column + canonical todo title visible. MUST be last (flips layout, breaks chat input on narrow widths) Pills intentionally skipped (track in follow-up): - Excalidraw Diagram — depends on mcp.excalidraw.com reachability, turning D5 reliability into a 3rd-party uptime bet - Calculator App — sandboxed iframe makes assertions cross-frame-fragile; generateSandboxedUi already covered by d5-gen-ui-open on a different demo route (would duplicate coverage) Probe uses the runner's structural ConversationPage type for most assertions (via page.evaluate helpers in the d5-chat-css globalThis-cast pattern, which keeps the harness's Node-only tsconfig clean of DOM lib types). Schedule Meeting narrows to an extended Page type with click() — same runtime-guarded cast used in d5-hitl-text-input — so it can dispatch the HITL slot click. Fixture file expanded from 2 to 15 entries covering all 7 turns plus their multi-stage chains (Sales Dashboard primary + secondary LLM + post-tool; Task Manager enableAppMode → manage_todos → narration). Re-bundled into showcase/aimock/d5-all.json (additions only — no other fixtures changed). Conversation runner reports failure_turn so per-pill failure isolation is preserved on the dashboard's drilldown without needing 7 separate D5 literals. |
||
|
|
e11c1d0810 |
feat(showcase): D5 conversation probe for beautiful-chat (langgraph-python)
Beautiful Chat was capped at D4 in the dashboard because it had no
dedicated D5 probe and was deliberately excluded from CATALOG_TO_D5_KEY
(commit
|
||
|
|
5b11748065 |
docs(react-core): refresh IntelligenceIndicator auto-mount comment
The previous comment referenced a "200 ms poll interval" that the indicator no longer uses (polling was removed when we switched to the tool-call pending-grace timer). Updates the rationale to mention the current self-gates (latest matching-assistant slot + pending grace window). |
||
|
|
ee1856f1ba |
refactor(react-core): minimize MemoizedCustomMessage delta to just the auto-mount
Reverts the cosmetic changes that crept in alongside the auto-mount edit — restores `stateSnapshot?` (always passed at runtime, no functional difference), the original concise comments around the memo's comparison function, and the original combined value+type imports. The only remaining framework change in this PR is the new auto-mount block: when `copilotkit.intelligence !== undefined` and the message is an assistant message, push an `<IntelligenceIndicator>` after the message slot. Indicator e2e suite still green (10/10). |
||
|
|
af9ea8b987 |
refactor(core,docs): rename ProxiedCopilotRuntimeAgent.remoteAgentId → runtimeAgentId
Renames the proxy-config field, the field on the agent instance, and all matching references in tests and the useCopilotKit reference page. "runtime" reads more naturally now that the proxy concept is documented as "a local agent that delegates to a runtime agent" rather than "remote agent" — the latter conflates with `remoteAgents` (the registry of agents fetched from the runtime), which keeps its name. No behavioral change; the field still controls the outbound REST URL used by the proxy. |
||
|
|
b63602241d |
refactor(react-core): drop MemoizedCustomMessage's run-state inputs
Removes the numberOfMessagesInRun, isInLatestRun, and isRunning props on MemoizedCustomMessage along with the per-render runMetadata derivation that fed them. Authored renderers observe run state via useAgent's OnRunStatusChanged / OnMessagesChanged subscriptions, which forceUpdate the renderer independently of the memo's bail-out — the extra invalidation inputs added nothing for that canonical path and only masked staleness for renderers that read run state from closure without subscribing. The IntelligenceIndicator itself uses useAgent and remains correct. Net change: ~95 lines removed; one less O(n) scan through messages per chat re-render. All chat e2e tests (587) pass, including the indicator suite (10). |
||
|
|
77dab3766a |
refactor(core,docs): rename ProxiedCopilotRuntimeAgent.remoteAgentId → runtimeAgentId
Renames the proxy-config field, the field on the agent instance, and all matching references in tests and the useCopilotKit reference page. "runtime" reads more naturally now that the proxy concept is documented as "a local agent that delegates to a runtime agent" rather than "remote agent" — the latter conflates with `remoteAgents` (the registry of agents fetched from the runtime), which keeps its name. No behavioral change; the field still controls the outbound REST URL used by the proxy. |
||
|
|
cfe4744024 |
docs(shell-docs): use prose "public license key" in CTA copy
Three CTA `body` strings rendered "publicLicenseKey" as plain prose, which reads as code (camelCase identifier) where the surrounding sentence is conversational. Switches to "public license key" — the phrase, not the prop name. Code samples and reference docs that reference the actual `publicLicenseKey` prop are unchanged. |
||
|
|
14469bedf4 |
feat(shell-docs): add useThreads at canonical reference path + content parity
The useThreads page existed in shell-docs at \`src/content/docs/reference/v2/hooks/useThreads.mdx\` but that tree isn't routed — the canonical reference renderer reads from \`src/content/reference/\`, not \`src/content/docs/reference/\`. As a result \`/reference/hooks/useThreads\` 404'd while the upstream docs have had a working useThreads page for weeks. Moves the page to the canonical location so it resolves at \`/reference/hooks/useThreads\`, and pulls the rest of the threads content stack into parity with upstream: - Add \`OpsPlatformCTA\` to the reference renderer's component map so hook reference pages can host sign-up CTAs (used here on useThreads itself). - Recreate useThreads at the canonical path. Drops the \`<ThreadsEarlyAccess>\` wrapper (canonical reference dir doesn't use it — threads is GA, no banner) and the \`doc_type: reference\` frontmatter field (canonical hooks use plain title + description). Keeps the local additions: \`<OpsPlatformCTA>\` placement and the \`lastRunAt\` PropertyReference (deliberately kept per commit 9f18b50f0). - Fix cross-links to useThreads in threads.mdx and the shared snippet to point at the canonical \`/reference/hooks/useThreads\` instead of the broken \`/reference/v2/hooks/useThreads\`. - Bump the prerequisite from \`@copilotkit/react-core v1.50+\` to \`v1.56+\` in threads.mdx and the shared snippet to match upstream. Out of scope: the broader \`/reference/v2/hooks/\<Name\>\` broken-link problem across other shell-docs pages (useFrontendTool, useAgent, etc. — same dirname mismatch but for hooks unrelated to this PR). That's tracked under PDX-103 / PDX-84. Page-structure differences from upstream are preserved per the shell-docs IA decision to drop the \`learn/\` concept: \`learn/threads\` stays \`premium/threads-explained\`, \`learn/intelligence-platform\` stays \`premium/intelligence-platform\`, \`learn/tutorials/...\` stays \`tutorials/...\`. |
||
|
|
a5a48bd94e |
docs(shell-docs): rebrand "CopilotKit platform" → "Enterprise Intelligence Platform"
Mirrors upstream PR #4642 across shell-docs prose. Three patterns collapsed into one canonical name: - "CopilotKit platform" → "Enterprise Intelligence Platform" - "CopilotKit Intelligence Platform" → "Enterprise Intelligence Platform" - "Intelligence Platform" → "Enterprise Intelligence Platform" Also corrects the "a Enterprise" → "an Enterprise" article mismatch the rename leaves behind in self-hosting prerequisites (vowel-sound rule). URL slugs (/learn/intelligence-platform, /premium/intelligence-platform) are left as-is — text-only rename. Generated artifacts (search-index.json, demo-content.json) refresh on the next predev / prebuild script. PDX-113. |
||
|
|
835a55d0ba |
feat(shell-docs): place OpsPlatformCTA across MDX pages
Mirrors the placements upstream docs/ shipped in PR #4592 (Wave 1) and PR #4642 (Wave 2 — restored threads pages). 22 placements total: 18 direct ports of upstream surfaces, 3 path-adjusted (learn/* → premium/* or tutorials/*), and 1 structural (root prebuilt-components → its shell-docs directory index). Surface identifiers match upstream so PostHog `try_for_free_clicked` events can be reasoned about across the cutover. Skipped: - `quickstart.mdx` (root) — routing shim, no real content - `(root)/index.mdx` — shell-docs has no MDX docs landing - Per-framework integration `index.mdx` files — shell-docs has no per-framework overview pages, the upstream FrameworkOverview afterFeatures slot has no equivalent - `reference/v2/components/{CopilotChat,CopilotKit}.mdx` and `reference/v2/index.mdx` — shell-docs reference layout differs PDX-110. |
||
|
|
1685ba84e3 |
feat(shell-docs): port OpsPlatformCTA component
Adds the four-variant sign-up CTA (card / inline / tile / info) that upstream docs/ uses to drive the Enterprise Intelligence Platform funnel. Wires it into the shared MDX registry so MDX pages can drop `<OpsPlatformCTA>` inline. Adapted to shell-docs conventions: - Tokens swapped from indigo/purple Tailwind utilities to the --accent / --violet-light / --border / --text* CSS variables that shell-docs already uses, so the visuals match the rest of the site. - Dropped the dark: modifiers (shell-docs has no dark theme yet). - Replaced the lucide-react import with three inline SVG components (ArrowRight, Info, Sparkles) — shell-docs deliberately avoids the lucide dep, the mdx-registry uses emoji fallbacks for icons. - Removed the client-side posthog.capture for try_for_free_clicked. shell-docs ships server-side PostHog (middleware) only and has no posthog-js; UTM params on the dashboard URL remain the source of truth for click attribution. Surface props are preserved as the utm_content value. PDX-109. |
||
|
|
23d4770537 |
feat(showcase): hand-rolled headless-chat suggestion chips + parity across 17 integrations (#4669)
## Summary
Adds hand-rolled persistent suggestion chips to the `headless-simple`
and `headless-complete` demos in the langgraph-python north-star,
propagates the same surface to the other 17 showcase integrations, and
adds a deterministic aimock fixture so a new chip-click e2e test
("Largest continent") rounds-trips against a stable `Asia is the largest
continent…` response across all 18 demos.
## What changed
**Phase 0 — north-star (commit `7cbc5ea8`)**
- `showcase/aimock/feature-parity.json` — new fixture: `What is the
largest continent?` → `Asia is the largest continent — about 30% of
Earth's land area, home to over 4.6 billion people.`
- `langgraph-python/src/app/demos/headless-{simple,complete}/page.tsx` —
refactor `send` / `handleSubmit` to accept `(override?: string)` so chip
clicks dispatch synchronously without a `setInput` round-trip; render a
persistent `<div data-testid="headless-suggestions">` chip row above the
composer with 5 canonical entries; remove the dead
`useConfigureSuggestions` call from headless-complete (it was
registering suggestions nothing rendered).
- `langgraph-python/tests/e2e/headless-{simple,complete}.spec.ts` —
append one new test in each spec asserting chip click → user message →
`Asia` reply.
**Phase 1 — parity propagation across 17 integrations (commit
`4882c61f`)**
- Spec files `headless-simple.spec.ts` and `headless-complete.spec.ts`
are now byte-identical to the north-star in every integration (10 tests
each = 5 simple + 5 complete; verified via `cmp` for all 34 spec files).
- The 5-entry `suggestions` const is byte-identical between every
integration's simple and complete demos.
- All 17 integrations now expose the same selector surface (canonical
headings, empty-state text, `data-testid="headless-complete-messages"`,
dynamic placeholder, `rounded-br-sm` user bubble, no CopilotChat-default
testids).
**Glue preserved per integration** (verified by post-blitz code review):
- `built-in-agent`: `<CopilotKitProvider runtimeUrl="/api/copilotkit"
useSingleEndpoint>` + `agentId: "default"`
- `google-adk` / `llamaindex`: `agentId: "headless_simple"` /
`"headless_complete"` (Python-style underscores)
- `claude-sdk-typescript`: headless-complete
`runtimeUrl="/api/copilotkit-headless-complete"`
- `spring-ai`: 70-line `deduplicateMessages` adapter workaround +
`useMemo` import preserved verbatim
- All `@region[...]` markers preserved in place
**Adapter-specific decisions worth flagging in review:**
- `google-adk` headless-complete: rewrote `message-list.tsx` from
`msg-user`/`msg-assistant`/`agent-thinking` testid scheme to the
canonical `headless-complete-messages` wrapper; rewrote `input-bar.tsx`
placeholder to canonical dynamic; added the missing subtitle and
empty-state hint
- `ms-agent-dotnet`: extracted inline composer to a new `input-bar.tsx`
to match north-star structure
- `llamaindex`, `ms-agent-python`: added the canonical empty-state hint
(was missing entirely)
- `agno`, `built-in-agent`, `crewai-crews`, `mastra`, `ms-agent-dotnet`,
`pydantic-ai`: replaced per-integration empty-state hint with the
canonical Excalidraw line — chosen for parity over per-integration
accuracy (some demos don't actually wire an Excalidraw tool; alignment
was the explicit goal)
## Verification
- `validate-parity.ts`: 18/18 packages pass, 0 MUST failures
- `aimock-fixtures` test suite: 18/18 pass
- aimock fixture probed directly: `What is the largest continent?`
returns the canonical Asia response
- Each propagation slot reported `tsc --noEmit` clean (0 new errors) +
`playwright --list` shows all 10 expected tests
- Code review (`pr-review-toolkit:code-reviewer`) on the full diff: 0
Critical / Important / Minor findings, 1 stylistic nit (north-star
`input-bar.tsx` `onSubmit` type contravariant-loose, harmless)
## What was NOT done
Live per-integration Playwright runs against rebuilt Docker images. The
17 containers would each need a no-cache rebuild (~5-15 min each = hours
total) and the canonical local-test path is `showcase test <slug>` per
the existing CLI / CI pipeline. Static + structural verification covers
the propagation pattern.
## Test plan
- [ ] Run `showcase test <slug>` (or equivalent CI job) for at least one
drift-heavy integration: `google-adk` (testid scheme rewrite),
`built-in-agent` (provider glue), `spring-ai` (dedup workaround),
`llamaindex` (added testid + empty-state)
- [ ] Run the existing per-integration Playwright suites for at least
the north-star (`langgraph-python`) to confirm the new chip test passes
against a real backend + aimock
- [ ] Confirm aimock fixture validation still passes after deploy
|
||
|
|
602fb2d190 |
fix(showcase): trim headless-simple chips to in-surface set + add tool wildcard to google-adk/headless-complete
The validate-fixture-tool-surface check on PR #4669 flagged 18 drift violations: every headless-simple demo carried 'Weather in Tokyo' / 'AAPL stock price' / 'Highlight a note' / 'Sketch a diagram' chips that substring-match aimock fixtures returning tool calls (get_weather / get_stock_price / highlight_note / etc.) — but headless-simple demos only register 'show_card' via useComponent. Tool-call dispatch had no matching renderer. Trim the headless-simple chip list to two in-surface entries: - 'Profile card' → 'Show me a profile card for Ada Lovelace' (existing show_card fixture; show_card is already registered by useComponent). - 'Largest continent' → 'What is the largest continent?' (text-only fixture from Phase 0; no tool dependency). The chip-click e2e test only asserts on the 'Largest continent' chip, so the trim is test-compatible. Headless-complete keeps the canonical 5-chip list (its tool surface covers weather/stock/highlight/excalidraw via tool-renderers.tsx and backend agents). For google-adk/headless-complete: add a useDefaultRenderTool() wildcard catch-all. The validator looks at page.tsx + hooks/* and a backend agent file; google-adk's tool registrations live in tool-renderers.tsx (unparsed) and there's no matching agents/headless_complete.py file, so the validator saw an empty tool surface. The wildcard registers '*' which matches every fixture tool — same pattern north-star already uses in its own tool-renderers.tsx. |
||
|
|
8623c4a9b5 |
fix(react-core): IntelligenceIndicator drops polling, gates on tool-call pending window
Replaces the agent.isRunning-driven phase entry (and its 200 ms polling fallback) with a 100 ms grace timer on unresolved matching tool calls. Replay flashes (tool call + result in the same tick during connectAgent history hydration) no longer cross the threshold, so the pill stops appearing on completed historical runs. Spinner exits as soon as either agent.isRunning falls or a "real follow-up" message arrives — assistant prose, a fresh user turn, or anything that isn't a tool result / empty-content tool-call wrapper. Multi-step tool chains stay on a single continuous pill (the latest-matching-assistant slot still moves between messages without a fade animation when the next bash assistant lands). Polling and the snapshot-subscriber comment were a misdiagnosis of a test artifact: useAgent's OnRunStatusChanged subscription is what the rest of CopilotKit (CopilotChat stop button, MCPAppsActivityRenderer, chat suggestions) relies on for isRunning falling-edge re-renders. Tests cover three new cases: replay-flash suppression, multi-step continuity across tool-result interleaving, and exit-on-prose-followup. |
||
|
|
c95d33d1fc |
fix(showcase/dashboard): cap maxPossible at D5 and align live-cell + RefDepth chips (#4667)
Follow-up to #4664 — same root cause, two more callsites and one inflation. ## Two issues ### 1. Live cell + Ref Depth column still rendered red `composed-cell.tsx`, `feature-grid.tsx` (via `ref-depth-column.tsx`) had the same regression-vs-ceiling collision the matrix views did: they passed `regression={depth.isRegression}` to `DepthChip`, and `regression` short-circuits the chip to red regardless of `maxDepth`. Switched them to pass `maxDepth={depth.maxPossible}` only. `RefDepthCellProps.regression?` flips to `maxDepth?` to stop propagating the dead prop. ### 2. `maxPossible` was inflated to 6 `computeMaxPossible` returned **6** whenever a D5 mapping existed, on the assumption D6 was structurally reachable. There is no per-feature D6 registry, so D6 is a stretch goal in practice — every D5 cell rendered amber as "1 below ceiling," even when it was the realistic ceiling. Cap at 5; D6-green cells still render green because `depthColorClass` treats `depth >= maxDepth` as at-ceiling. This restores the cap from commit `eda75a512` (*"D5 mapping means max=5 not 6 (D6 probes are rare)"*) which was lost in the subsequent depth thrash. `page.tsx` `healthStats` also dropped its `isRegression` short-circuit so the stats bar mirrors the chip's graduated logic instead of double-counting non-ceiling cells as red. ## Verified locally Pointed dev dashboard at production PocketBase + harness: - Before: 539 D5 cells **amber**, 162 D4 green - After: **701 green**, 0 amber, 0 red ## Test plan - [x] `depth-utils`, `depth-chip`, `parity-matrix`, `cell-matrix`, `composed-cell`, `feature-grid` test files — 115/115 passing - [x] Visual check on local dashboard against prod data — all wired cells now render green - [ ] On deploy, confirm matrix view at `dashboard.showcase.copilotkit.ai/#matrix:depth,health` matches local |
||
|
|
bf4bef3121 |
fix(showcase/beautiful-chat): render A2UI surfaces (fixed + dynamic schema) (#4668)
## Summary
Search Flights and Sales Dashboard pills on the langgraph-python
beautiful-chat demo now produce visible A2UI surfaces. Three independent
bugs were masking each other:
- **Tool args were silently rejected.** `Flight` TypedDict required `id`
+ `statusIcon`, which the aimock fixture doesn't supply. langchain
bounced the call with `flights.0.id: Field required` and the agent
surfaced the validation error string as the "tool result" — so the LLM
summarized "Two flights shown above" without any cards ever rendering.
Made `Flight` permissive (`total=False` then `list[dict]`); only the
fields `_build_flight_components` reads need to be there.
- **`search_flights` now expands flights into literal-children
FlightCards server-side.** The structural-children template form
(`Row.children = { componentId, path }`) doesn't reliably expand for our
custom catalog — the working sibling demo (`a2ui-fixed-schema`) avoids
the form for the same reason.
- **Sales Dashboard pill went into a tool-call loop** because the
`userMessage + toolName` fixtures matched both the initial call and the
post-tool turn. Hoisted the `toolCallId` fixture above them so the
follow-up turn returns content and breaks the loop. Three new fixtures
at the top of `feature-parity.json`: a follow-up content match, the
secondary-LLM `render_a2ui` call, and the primary `generate_a2ui` call.
Reintroduced custom `Row`/`Column` renderers with `gap` support — the
basic catalog versions ignore it and the dashboard cards were squished.
Children are array-of-strings only (matches what the agent and fixture
emit).
## Test plan
- [x] All 7 tests in
`showcase/integrations/langgraph-python/tests/e2e/beautiful-chat.spec.ts`
pass (45s). Two new ones cover both pills end-to-end: `Search Flights
pill renders FlightCard surface from A2UI fixed schema` and `Sales
Dashboard pill renders A2UI dashboard surface`.
- [x] `pnpm test aimock-fixtures` passes (18/18) — fixture schema
validator is happy with the 3 new entries.
- [x] Manual visual confirmation: both pills render full surfaces with
proper card spacing.
- [x] No regression on existing `Toggle Theme` / `Pie Chart` / `Bar
Chart` pills.
## Notes
- Added a 3-second `waitForTimeout` to the spec's `beforeEach` so the v2
chat provider hydrates before suggestion clicks dispatch. Without it,
the click can race past hydration and silently no-op (the existing
pre-existing tests happened to be tolerant of this; the A2UI ones
aren't).
- System prompt cleaned up: dropped references to tools that don't exist
(`log_a2ui_event`, "enable app mode") and named `pieChart`/`barChart`
explicitly.
|
||
|
|
7baf4d05e8 |
fix(react-core): IntelligenceIndicator pill shrinks to content width
The auto-mount in `CopilotChatMessageView` puts the indicator inside a flex column container (`cpk:flex cpk:flex-col`) whose default `align-items: stretch` was overriding the pill's intended `display: inline-flex` shrink-to-content behaviour, leaving the pill stretched to the full chat width — out of proportion with the short label. Add `align-self: flex-start` to opt the pill out of the parent's stretch. Pill renders at content width, anchored to the chat's left edge in line with the assistant message bubble it represents. |