The @ag-ui/core Message type resolves to unknown when zod v4 is
present in the dependency tree (zod v4 lacks ZodDiscriminatedUnion,
so z.infer<typeof MessageSchema> becomes unknown). This caused
TS2339 errors on .role, .toolCallId, and .id property accesses
in render-tool-calls.ts and copilot-chat-message-view.ts.
Fix by defining a structural BaseMessage interface with the
minimal shape needed (id, role, content) and casting through it
in copilot-chat-message-view.ts; in render-tool-calls.ts use
Record<string, unknown> intermediate cast in the type guard.
## Summary
- Runs `oxfmt --write .` to fix 25 files failing the `check-format` CI
step on main
- All files are in `showcase/` (shell-dashboard, integrations, harness,
debugging docs)
## Test plan
- [x] `pnpm run check-format` passes locally
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Headers in the announcement banner now have proper hierarchy (h1/h2/h3
distinct sizes); body bumped to 13px / 1.55 line-height for readability.
- Code blocks get dark theme styling with horizontal scroll, a trailing
80px spacer so the end of long commands is fully readable, and a
brand-lavender copy button (with "Copied" confirmation in `#eee6fe` /
`#6430ab`).
- Announcement banner moved out of the non-scrollable drag-handle header
into the `#cpk-main-scroll` container so expanding it no longer squeezes
the resize handle and main content off-screen (folds in @claude's fix
from `tyler/funny-shtern-1a95ef`).
The prior commit accidentally re-included a local-only flip of
ANNOUNCEMENT_URL to the draft endpoint while staging the unrelated
copy-button timeout fix. Restore the production URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous copyResetTimeout field was a single instance-level number,
shared across every code block in a multi-block announcement. Clicking
Copy on block A then block B cancelled block A's reset timer, leaving
block A stuck on "Copied" forever.
Switch to a WeakMap<HTMLButtonElement, number> so each button manages
its own pending reset and is naturally cleaned up when the announcement
re-renders. Also keep aria-label in sync with the visible text label so
screen-reader users hear "Code copied" while sighted users see "Copied".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CR-loop fixes from a 7-agent unbiased review on the announcement banner
work:
- Replace deprecated unescape/escape with TextEncoder/TextDecoder in
encodeBase64/decodeBase64, dropping the half-decoded fallback path.
- Drop unsafe `as HTMLElement` and `as HTMLButtonElement` casts in
handleAnnouncementContentClick; the .announcement-code__copy selector
does not enforce HTMLButtonElement, so use instanceof guards.
- Coalesce overlapping copy-button resets via a class field timeout id
and a constant "Copy" label; previously a rapid double-click captured
"Copied" as the original label and pinned the button text.
- Pass async: false to marked.parse for a type-honest string return.
- Fold escapeHtmlAttr into the module-level escapeHtml helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the duplicate escapeHtmlText method with the existing module-level
escapeHtml helper that has identical behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Differentiate h1/h2/h3 sizes and bump body type for readability
- Add code-block styling with horizontal scroll, trailing spacer, and a
copy button (brand lavender on success)
- Move announcement banner from the non-scrollable header into the main
scroll container so an expanded banner no longer pushes the resize
handle and content off-screen
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
⚠️ **Docs sync — MANUAL REVIEW REQUIRED**
This PR was auto-opened because the docs-sync script detected
showcase-local modifications overlapping with upstream changes.
The script attempted a best-effort 3-way merge:
- Where `git merge-file` produced a clean merge, the merged content was
written.
- Where `git merge-file` produced conflict markers, **upstream content
was written as-is** and showcase-local modifications were overridden.
**Manual review required.**
### Review items
```
Files where 3-way merge FAILED — upstream content written as-is, local modifications overridden. Manual review REQUIRED before merging this PR:
- docs/content/docs/(root)/inspector.mdx
- docs/content/docs/integrations/agent-spec/quickstart.mdx
- docs/content/docs/integrations/built-in-agent/server-tools.mdx
- docs/content/docs/integrations/langgraph/deep-agents.mdx
Files auto-merged via 3-way merge (clean, no conflict markers — still worth a glance):
- docs/content/docs/integrations/aws-strands/quickstart.mdx
- docs/content/docs/integrations/langgraph/quickstart.mdx
```
### Source
- Upstream ref:
[`330b4eb06`](https://github.com/CopilotKit/CopilotKit/commit/330b4eb06)
- Workflow run:
https://github.com/CopilotKit/CopilotKit/actions/runs/25185454071
**Review before merging.** Auto-merge is intentionally disabled
for `needs-review` PRs — confirm the upstream-wins sections
preserve any intentional showcase-local divergence you want to
keep, then merge manually.
The auto-sync removed the lastRunAt entry from the useThreads API reference,
but the field is still present on the Thread type and drives sort behavior in
packages/core/src/threads.ts. Restoring the doc keeps the API reference
complete.
<!--
Thank you for sending the PR! We appreciate you spending the time to
work on these changes.
Help us understand your motivation by explaining why you decided to make
this change.
**Please PLEASE reach out to us first before starting any significant
work on new or existing features.**
By the time you've gotten here, you're looking at creating a pull
request so hopefully we're not too late.
We love community contributions! That said, we want to make sure we're
all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align
with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in
progress.
As described in our contributing guide, please file an issue first:
https://github.com/ag-ui-protocol/ag-ui/issues
Or, reach out to us on Discord: https://discord.com/invite/6dffbvGU3D
You can learn more about contributing to copilotkit here:
https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md
Happy contributing!
-->
## What does this PR do?
(Describe the changes introduced in this PR)
- Logo component: "Logo" → "CopilotKit" (both light/dark variants)
- Examples carousel: empty alt → example.title
- Scarf tracking pixel: add aria-hidden so SR/audit tools skip it
## Related PRs and Issues
- (Direct link to related PR or issue, if relevant)
## Checklist
- [ ] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
- [ ] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
## Summary
- Adds a reusable `OpsPlatformCTA` component with four visual variants
(card, info, inline, tile), PostHog `cta_clicked` instrumentation, and
UTM-tagged links to the dashboard
- Places sign-up CTAs across topical docs pages, integration overview
pages, manual-setup quickstarts, premium pages, and the shared
prebuilt-components snippet (covers all per-integration prebuilt pages)
- Repoints the navbar "Free Developer Access" link to the dashboard with
matching click tracking
- Adds an `afterFeatures` slot to `FrameworkOverview` so MDX can inject
content below the supported-features section
- Rewrites the CLI step on the eight framework quickstarts that have a
scaffold (ADK, Agno, AWS Strands, LangGraph, LlamaIndex, Mastra,
Microsoft Agent Framework, Pydantic AI) to use the interactive flow and
describe the prompts (project name, platform Yes/No with sign-up link,
framework picker)
Coverage: ~13% of docs pages, focused on the highest-traffic surfaces
and topical landing pages.
## Test plan
- [ ] `/`, `/quickstart`, `/prebuilt-components`, `/shared-state`,
`/inspector` show their CTAs in the expected position
- [ ] Integration overview pages (`/built-in-agent`, `/langgraph`,
`/adk`, `/aws-strands`, `/microsoft-agent-framework`) render the CTA
above the fold
- [ ] Each of the 13 per-integration `/{framework}/prebuilt-components`
pages renders the inline CTA via the shared snippet
- [ ] Each of the 8 framework quickstarts shows the new CLI walkthrough
(Yes-first prompt, dashboard sign-up link, correct framework label)
- [ ] Navbar still shows "Talk to Our Engineers" alongside the repointed
"Free Developer Access" link
- [ ] DevTools Network: clicking any CTA sends one `cta_clicked` PostHog
event with `{surface, variant, target, page_path}`
- [ ] Destination URL on every CTA ends with
`?utm_source=docs&utm_medium=cta&utm_campaign=intelligence&utm_content=<surface>`
Renames the docs CTA tracking event from `cta_clicked` to
`try_for_free_clicked` to match the per-event custom event names used
on the marketing website, and uses a single `location` string property
in place of the previous `surface` / `variant` / `target` / `page_path`
shape. Surface identifiers are normalized to underscored snake_case to
match the location values already used on the website.
Same change applies to the docs navbar handler that fires when a
visitor clicks the Free Developer Access link.
Adds a sign-up CTA to the shared `prebuilt-components` snippet so it
appears on all twelve per-integration `/{framework}/prebuilt-components`
pages that consume it, and adds a matching CTA to the LangGraph
prebuilt-components page (which uses custom content rather than the
shared snippet).
Moves the Built-in Agent overview CTA from below the features grid to
above the first H2 so it lands above the fold on standard viewports.
Replaces the framework-specific `npx copilotkit@latest create -f <fw>`
command with the interactive `npx copilotkit@latest create` flow on the
eight framework quickstarts that have a CLI scaffold (ADK, Agno, AWS
Strands, LangGraph, LlamaIndex, Mastra, Microsoft Agent Framework,
Pydantic AI).
Each quickstart's "Run our CLI" step now describes the three prompts
the CLI walks the user through — project name, the platform Yes/No
question (with a sign-up link to the dashboard), and the framework
choice. Framework labels match the strings rendered by the CLI's
interactive select-input so the docs stay aligned with the runtime
prompt.
Drops the per-language Tabs blocks on LangGraph and Microsoft Agent
Framework since the language variant is now picked through the CLI
prompt rather than encoded as a flag.
Places dashboard sign-up CTAs on topical pages, threads guides,
reference pages, and integration overview pages. Each CTA is tagged
with a stable surface identifier for PostHog attribution and routes to
the dashboard with matching UTM parameters.
Placements include:
- Home and quickstart landing pages
- Prebuilt-components, shared-state, and chat-related reference pages
- Threads how-to, tutorial, reference, and per-integration threads pages
(via the shared snippet)
- Inspector, event-inspector, and learning explainer pages
- Premium overview, observability, headless-ui, and self-hosting pages
(via the shared snippets)
- Integration overview pages — placed via the new afterFeatures slot on
the four FrameworkOverview-based pages (LangGraph, ADK, AWS Strands,
Microsoft Agent Framework) and below the features grid on Built-in
Agent
- Manual-setup quickstart pages (a2a, ag2, agent-spec, built-in-agent,
crewai-flows, deepagents)
Also normalizes platform copy across the affected pages.
Adds an optional `afterFeatures` ReactNode prop to the FrameworkOverview
landing-page component, rendered as a section between the supported
features grid and the architecture section. Lets the hosting MDX page
inject contextual content (links, callouts, sign-up cards) below the
final feature without needing to modify the component for each
integration.
Introduces a reusable OpsPlatformCTA component with four visual variants
(card, info, inline, tile) for placing dashboard sign-up calls-to-action
across the docs. Each click captures a `cta_clicked` PostHog event tagged
with surface, variant, and page path, and navigates to the dashboard with
UTM parameters identifying the source surface.
Registers the component in both MDX provider maps (home and integrations
slug routes) so it can be used in any MDX file.
Repoints the navbar "Free Developer Access" link to the dashboard and
wires the same PostHog tracking to its left and right placements.
## Summary
Fixes GitHub Actions template injection (CWE-78) across three workflow
files. Untrusted PR event data (`title`, `head.ref`, `base.ref`, SHAs,
`user.login`) was interpolated directly into shell `run:` blocks via
`${{ }}`, allowing arbitrary code execution on the runner via a crafted
PR title or branch name.
**Fix:** Move all untrusted expressions to `env:` blocks and reference
them as shell variables (`${VAR}`) instead. This is the standard
mitigation recommended by GitHub's security hardening guide.
### Affected files
- **test_smoke-starter.yml** — PR title, user login, head SHA in the
"Capture failure cause" step
- **publish-release.yml** — PR head ref (branch name) in the "Extract
scope from branch" step
- **static_quality.yml** — PR base ref in the "Collect PR-changed files"
step; base/head SHAs in the "Validate PR commits with commitlint" step
All other workflow files were audited and already use safe patterns
(`env:`, `with:`, or `concurrency:` blocks).
## Test plan
- [ ] CI passes on this PR (the workflows themselves are exercised by PR
events)
- [ ] Grep confirms no remaining `${{ github.event.pull_request.*`
inside `run:` blocks
Move untrusted PR event data (title, head ref, base ref, SHAs) from
inline ${{ }} interpolation in shell run: blocks to env: blocks,
referencing them as shell variables instead. This prevents arbitrary
code execution via crafted PR titles or branch names.
Affected workflows:
- test_smoke-starter.yml: PR title, user login, head SHA
- publish-release.yml: PR head ref (branch name)
- static_quality.yml: PR base ref, base SHA, head SHA
## Summary
- Removed the dark `#0a0a0f` background `<rect>` from `icon.svg` — the
favicon now shows only the shield+kite shape on a transparent background
- Converted `og-image.png` from RGB to RGBA and made all background
pixels (`#0a0a0f`) fully transparent, leaving the 17k content pixels
(shield+kite graphic) intact
## Test plan
- [ ] Open showcase-dashboard locally, verify the browser tab favicon
shows the shield without a dark square
- [ ] Check the og:image preview (e.g. via https://www.opengraph.xyz/)
to confirm the shield renders on transparent background
## Summary
- Add "Isolated Test Runs" section to `showcase/DEBUGGING.md` covering
how `--isolate` works (temp overlays, slot-based ports, project name
scoping), parallel safety, and troubleshooting stale state from the old
behavior.
- Add "Isolated Test Runs" section to `showcase/RUNBOOK.md` with
operational notes: when to use `--isolate`, parallel run limits, orphan
container cleanup, and stale slot cleanup.
Documents the rewrite from PR #4570, which replaced the old in-place
mutation approach with temp overlay files that never touch originals.
## Test plan
- [ ] Verify DEBUGGING.md renders correctly on GitHub
- [ ] Verify RUNBOOK.md renders correctly on GitHub
- [ ] Confirm section placement matches existing document structure and
style
The --isolate flag was rewritten in PR #4570 to use temp overlay
files instead of mutating originals in place. Add sections to
DEBUGGING.md (how it works, troubleshooting) and RUNBOOK.md
(operational notes for parallel runs and cleanup).
## Summary
- Adds `if: false` to the `create-check` job in
`showcase_eval_check.yml`
- The check is failing on every PR (see screenshot in conversation)
- Easy to re-enable: just remove the `if: false` line
## Test plan
- [ ] Verify new PRs no longer show the failing "Showcase: Eval Check"
check
## What does this PR do?
Corrects scaffolded template instructions so generated projects match
their actual package scripts and runtime requirements. The updates
remove stale duplicate setup steps, fix provider environment examples,
align Python version and uv guidance, and document that the threads
template npm run dev starts its Docker Compose infrastructure.
## Related PRs and Issues
- Companion Intelligence CLI PR:
https://github.com/CopilotKit/Intelligence/pull/160
## Checklist
- [x] I have read the Contribution Guide
- [x] If the PR changes or adds functionality, I have updated the
relevant documentation
- [ ] Allow edits by maintainers is checked
## Summary
Polish pass on the deep-agents-finance-erp showcase to reduce visual
noise and make the chat surface feel more like a real assistant.
- **Persistent follow-up suggestion chips** above the input. The third
chip rotates based on the currently loaded dashboard so we never suggest
switching to the view the user is already on (e.g. on Cost Control the
chip becomes "Cash Flow Risk", on Cash Flow Risk it becomes "Cost
Control").
- **Hover-only assistant toolbar on the last turn.** The copy icon no
longer floats between tool-call cards mid-conversation; it only appears
on the latest assistant message and only when the user hovers it.
- **Cleaner research / projections tool render.** Replaced the raw
markdown-table preview under `do_research` / `do_projections` cards (`|
Metric | Amount | |---|---:|...`) with a "Completed data gathering" /
"Completed projections" status caption. Full results still available
behind the chevron expand.
- **Natural-language intent routing in the orchestrator prompt.**
Spending / cost / cash-flow / revenue / executive-overview questions now
resolve to `do_research` → `load_dashboard` against the matching
pre-built template (no `save_dashboard` + `manage_dashboard(reset)` +
`update_dashboard` churn). Approval-context invoice questions ("do we
have any invoices for approval", "what needs to be paid") route to
`request_approval(invoice_payment)` instead of just charting.
## Files
-
examples/showcases/deep-agents-finance-erp/src/components/layout/shell.tsx
— suggestion chips, hover-only toolbar wrapper, dashboard-aware rotation
-
examples/showcases/deep-agents-finance-erp/src/components/chat/tool-card.tsx
— clean status caption for do_research / do_projections
- examples/showcases/deep-agents-finance-erp/agent/prompts.py —
intent-mapping rules for dashboards and approvals
## Test plan
- [ ] Open the chat and send any message — verify three chips appear
above the input on the second turn (Cash Position Chart / Approve
Payments / dashboard suggestion).
- [ ] Click "Show me where the company is spending its money" — verify
agent only calls `do_research` then `load_dashboard("Cost Control")`, no
`update_dashboard` / `save_dashboard` / `manage_dashboard`.
- [ ] After Cost Control loads, verify the third chip rotates to "Cash
Flow Risk".
- [ ] Hover over an assistant message — copy/toolbar icons fade in only
on the latest turn.
- [ ] Trigger `do_research` and verify the tool card shows "Completed
data gathering" instead of raw markdown.
- [ ] Ask "Do we have any pending invoices for approval?" — verify the
approval HITL dialog renders.
DocsLayer rendered unconditionally for docs-only features whenever
any overlay was active. Now respects the Docs toggle — docs-only
cells show Links (command) when Links is on, Docs when Docs is on,
empty otherwise.
## Summary
- Adds a **Talk to Our Engineers** CTA button to the right side of the
docs navbar, mirroring the new website's nav button.
- Wires the same PostHog `talk_to_us_clicked` event the website fires,
with `{ location: "docs_nav" }` so docs-originated clicks can be
segmented from website clicks (`"nav"`) in PostHog.
- Fixes a pre-existing layout bug where the navbar's slanted SVG borders
were sized in fixed pixels (`w-[24px] h-[60px]` / `xl:w-[29px]
xl:h-[72px]`) and didn't follow the nav's actual height once Chrome's
default font size was scaled above 16px — the wedge of page background
that leaked through the join is now sealed.
## Behavior
| Viewport | Button |
|---|---|
| `>= 1400px` | Visible |
| `1024–1399px` | Hidden (button text would otherwise force the left
links to wrap) |
| `< 1024px` | Hidden — mobile burger menu surfaces the link |
The button uses `text-muted-foreground` for the resting state to match
the existing nav links and an indigo `#7076D5` hover accent that matches
the active-link underline color. Target is
`https://copilotkit.ai/contact-us` (absolute since docs runs on the
`docs.` subdomain).
## Test plan
- [ ] Click the button on a wide viewport — navigates to
`https://copilotkit.ai/contact-us` and fires `talk_to_us_clicked` with
`{ location: "docs_nav" }` in PostHog.
- [ ] Resize from > 1400px down through 1024px and below — button shows
/ hides at the right thresholds with no left-link wrapping.
- [ ] Toggle dark mode — button border and text stay legible, hover
accent still indigo.
- [ ] Set Chrome's default font size to 20px and reload — no wedge gap
at the slanted-border join between the left and right pill containers.
Removes the unreleased Threads management surface (useThreads hook,
multi-conversation tutorial, the per-integration Threads how-to, the
shared snippet) and the Intelligence Platform / self-hosting pages
introduced alongside them, plus the ThreadsEarlyAccess gate that wrapped
them. The Learn landing page stays; just drops the Threads card and the
Intelligence Platform card. Sidebars (root, learn, reference/v2/hooks,
12 integrations + their premium subsections) are pruned to match.
<!--
Thank you for sending the PR! We appreciate you spending the time to
work on these changes.
Help us understand your motivation by explaining why you decided to make
this change.
**Please PLEASE reach out to us first before starting any significant
work on new or existing features.**
By the time you've gotten here, you're looking at creating a pull
request so hopefully we're not too late.
We love community contributions! That said, we want to make sure we're
all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align
with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in
progress.
As described in our contributing guide, please file an issue first:
https://github.com/ag-ui-protocol/ag-ui/issues
Or, reach out to us on Discord: https://discord.com/invite/6dffbvGU3D
You can learn more about contributing to copilotkit here:
https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md
Happy contributing!
-->
## What does this PR do?
(Describe the changes introduced in this PR)
## Related PRs and Issues
- (Direct link to related PR or issue, if relevant)
## Checklist
- [ ] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
- [ ] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
Removes the unreleased Threads management surface (useThreads hook,
multi-conversation tutorial, the per-integration Threads how-to, the
shared snippet) and the Intelligence Platform / self-hosting pages
introduced alongside them, plus the ThreadsEarlyAccess gate that wrapped
them. The Learn landing page stays; just drops the Threads card and the
Intelligence Platform card. Sidebars (root, learn, reference/v2/hooks,
12 integrations + their premium subsections) are pruned to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What this PR does
Adds the **Threads tab** to the CopilotKit web inspector. The tab lists
every thread the current agent has run and, when you click one, shows
three per-thread sub-tabs:
- **Conversation** — historical messages
- **Agent State** — state snapshot at the end of the thread
- **AG-UI Events** — full AG-UI event stream for the thread (tool calls,
state deltas, text chunks, etc.)
Data flows through new backend endpoints plus a Lit-based UI inside
`@copilotkit/web-inspector`. No extra package required for consumers.
## Changes by layer
### `@copilotkit/core`
- **`ThreadStoreRegistry`** — new class; keyed by `agentId`, lets
`useThreads()` and the inspector share a reference to the same store
without coupling the two packages directly
- **`onAgentRunStarted` subscriber event** — fires before
`agent.runAgent()` snapshots the subscriber list, so the inspector can
subscribe in time to receive run events
- `CopilotKitCore.getThreadStore()` / `registerThreadStore()` /
`unregisterThreadStore()` / `getThreadStores()` — public surface for
hook + inspector to interact with the registry
### `@copilotkit/runtime`
- **Thread HTTP handlers** — `handleListThreads`, `handleUpdateThread`,
`handleArchiveThread`, `handleDeleteThread`, `handleSubscribeToThreads`,
`handleGetThreadMessages`, plus the two new ones below
- **New: `GET /threads/:id/events`** and **`GET /threads/:id/state`** —
return the thread's AG-UI event stream and last `STATE_SNAPSHOT`
payload. Wired through both the in-memory runner and the Intelligence
platform's `_inspect/threads/:id/{events,state}` endpoints (consumed by
`CopilotKitIntelligence.getThreadEvents()` / `getThreadState()`)
- All mutations authenticate via `identifyUser(request)`; `userId` in
the request body is ignored
- **`InMemoryAgentRunner`** — stores thread history (messages +
compacted events per run); new `getThreadEvents()` and
`getThreadState()` methods; `getThreadState()` walks the compacted
events and returns the payload of the last `STATE_SNAPSHOT`
### `@copilotkit/react-core`
- **`useThreads` hook** — fetches threads, subscribes to a Phoenix
WebSocket channel for real-time metadata events, and
registers/unregisters its thread store with `CopilotKitCore` on
mount/unmount
### `@copilotkit/web-inspector`
- **Full Threads tab UI** — implemented in Lit as two custom elements
(`cpk-thread-list`, `ɵCpkThreadDetails`) living in-file alongside the
main `WebInspectorElement`
- Thread details fetches per-thread history via the new endpoints and
renders:
- Conversation: user/assistant bubbles, tool-call blocks with
expand/collapse, tool-call groups, reasoning/state-update chips,
generative-UI placeholders. Tool-call status is derived from parsed-args
presence — frontend-rendered generative-UI tools (charts, custom UI)
read `DONE` once args have streamed in, since they never produce a
`role: tool` result message
- Agent State: syntax-highlighted JSON of the last state snapshot
- AG-UI Events: colored event rows (by type family) with timestamped,
highlighted payloads. Off-screen rows use `content-visibility: auto` so
reveal cost is independent of total event count
- Right-side detail panel with thread metadata + activity counts,
toggled from the tab bar
- Tab DOM is mounted once per activation and hidden via `display:none`
when inactive, so switching between Conversation / Agent State / AG-UI
Events is a CSS swap rather than a render. Each panel's TemplateResult
is memoized by tuple of input references (`_conversation` + expand-state
Sets for conversation; `_fetchedState` for agent state; events array for
AG-UI events), so when the underlying data hasn't changed Lit's diff
short-circuits. JSON syntax highlighting is WeakMap-memoized by payload
reference
- `attachToCore()` guards the `core.getThreadStores()` call so consumers
still on an older `@copilotkit/core` don't throw when assigning
`inspector.core`
## Architectural notes
**Events/state via Intelligence:** the Intelligence platform persists
every AG-UI event in `cpki.run_events` keyed by run → thread and exposes
them via `_inspect/threads/:id/{events,state}`. The runtime's
`CopilotKitIntelligence.getThreadEvents()` / `getThreadState()` consume
those, so the same per-thread HTTP endpoints used by the in-memory path
serve Intelligence-backed consumers identically.
## Tests added
| File | What's new |
|---|---|
| `packages/core/src/__tests__/thread-store-registry.test.ts` | New —
register/get, replacement, no-op unregister, subscriber events |
| `packages/runtime/src/v2/runtime/__tests__/handle-threads.test.ts` |
`handleClearThreads`, `handleGetThreadMessages`, plus new
`handleGetThreadEvents` and `handleGetThreadState` describe blocks |
|
`packages/runtime/src/v2/runtime/runner/__tests__/in-memory-runner.test.ts`
| `getThreadMessages`, new `getThreadEvents` (stored events, unknown
thread, multi-run flattening), new `getThreadState` (null without
snapshot, returns last STATE_SNAPSHOT, most-recent across runs) |
| `packages/react-core/src/v2/hooks/__tests__/use-threads.test.tsx` |
Registry lifecycle (register on mount, unregister on unmount) |
| `packages/web-inspector/src/__tests__/web-inspector.spec.ts` | New
`ɵCpkThreadDetails caching` describe — threadId-change drops all panel
caches; conversation cache invalidates on `_conversation` reassignment
and on expand-state change; state and events caches invalidate on their
fetched-data reassignment |
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Adds a CTA button to the right side of the docs navbar mirroring the
website's nav button, including matching PostHog instrumentation. Fires
talk_to_us_clicked with { location: "docs_nav" } so docs-originated
clicks can be segmented separately from website clicks (which use
"nav"). Visible at viewports >= 1400px to avoid forcing the left
links to wrap; hidden below that breakpoint where the mobile burger
menu surfaces the link instead. Styled with text-muted-foreground to
match the existing nav links and an indigo #7076D5 hover accent that
matches the active-link underline.
The slanted SVG borders bridging the navbar's left and right pill
containers were sized with fixed pixels (w-[24px] h-[60px] /
xl:w-[29px] xl:h-[72px]). When users scale Chrome's default font size
above 16px, rem-based content inside the nav grows but the SVGs stay
fixed, leaving a visible wedge of page background at the top of the
join. Switch to h-full w-auto so the SVGs follow the container's
actual height while preserving their viewBox aspect ratio.
<!--
Thank you for sending the PR! We appreciate you spending the time to
work on these changes.
Help us understand your motivation by explaining why you decided to make
this change.
**Please PLEASE reach out to us first before starting any significant
work on new or existing features.**
By the time you've gotten here, you're looking at creating a pull
request so hopefully we're not too late.
We love community contributions! That said, we want to make sure we're
all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align
with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in
progress.
As described in our contributing guide, please file an issue first:
https://github.com/ag-ui-protocol/ag-ui/issues
Or, reach out to us on Discord: https://discord.com/invite/6dffbvGU3D
You can learn more about contributing to copilotkit here:
https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md
Happy contributing!
-->
## What does this PR do?
(Describe the changes introduced in this PR)
## Related PRs and Issues
- (Direct link to related PR or issue, if relevant)
## Checklist
- [ ] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
- [ ] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
## Summary
- When a Railway service deployed within the last 2 minutes, the D5
probe driver skips all features with green side rows instead of
launching a browser and producing false reds from deploy churn
- Discovery source now threads `deployedAt` (from
`latestDeployment.createdAt`) through to drivers via
`RailwayServiceInfo`
- Skip fires before script loader and browser launch so recently
deployed services cost zero probe resources
## Changes
**`showcase/harness/src/probes/discovery/railway-services.ts`**
- Added `deployedAt: string` to `RailwayServiceInfo` interface
- Added `createdAt` to the Zod schema for `latestDeployment` and the
GraphQL query
- Extracts `createdAt` in the enrichment loop and passes it through
**`showcase/harness/src/probes/drivers/e2e-deep.ts`**
- Added `DEPLOY_CHURN_GRACE_MS` constant (120,000ms = 2 minutes)
- Added `deployedAt` to the driver's input Zod schema
- Deploy-churn skip logic inserted after feature resolution, before
script loading and browser launch
- When `deployedAt` is within the grace window: emits green side rows
with `note: "skipped: deploy in progress (Ns ago)"` and returns
aggregate green with all features in `skipped[]`
**`showcase/harness/src/probes/drivers/e2e-deep.test.ts`**
- 8 new tests covering: skip path, normal execution when outside grace
window, backwards compat (absent/empty/unparseable `deployedAt`),
boundary at exactly `DEPLOY_CHURN_GRACE_MS`, and 0s-age edge case
## Test plan
- [x] `npx tsc --noEmit -p showcase/harness/tsconfig.json` passes
cleanly
- [x] All 40 e2e-deep driver tests pass (8 new + 32 existing)
- [x] All 58 railway-services discovery tests pass unchanged
- [ ] CI green