## What
Bumps `@copilotkit/license-verifier` from an exact `0.4.0` pin to a
`~0.4.2` patch range across:
- `package.json` — root `pnpm.overrides`
- `packages/runtime/package.json` — `dependencies`
- `packages/shared/package.json` — `dependencies`
- `pnpm-lock.yaml` — regenerated, resolves to `0.4.2`
## Why
Aligns the runtime/shared deps with the newly published
`@copilotkit/license-verifier@0.4.2`. Switching from an exact pin to
`~0.4.2` (`>=0.4.2 <0.5.0`) means future `0.4.x` patches are picked up
automatically, while `0.5.0`+ still requires an intentional bump.
## Notes
- `.npmrc` `minimum-release-age` guard was **not** modified; the
lockfile was regenerated with a one-off override since `0.4.2` was
freshly published.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Move runtime and shared deps (and the root pnpm override) from an exact
0.4.0 pin to ~0.4.2, so future 0.4.x patches are picked up automatically.
Regenerate pnpm-lock.yaml to resolve 0.4.2.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prevents nested-deps drift when consumers depend on @copilotkit/runtime
at a different version than voice's pinned version. Runtime is now a
peer dependency (consumer-controlled), with devDependencies retaining
the pin so voice's own tests and typecheck continue to work.
Picks up the forwarded-headers fix from ag-ui PR #1798
(https://github.com/ag-ui-protocol/ag-ui/pull/1798), which injects
agent.headers as config.configurable.copilotkit_forwarded_headers so
the LG dev server's HTTP-to-configurable bridge is no longer required
for X-AIMock-Context propagation. Closes the header-propagation gap
for showcase D5/D6 langgraph-typescript probes.
Picks up per-request header forwarding (onRequest hook + headerFactory)
and the prepareStream configurable+context partition fix from
ag-ui-protocol/ag-ui#1763. Together with copilotkit==0.1.91 on the
Python side (R3a), this unblocks D6 LGP/LGT header propagation.
The mergeConfigs() change in 0.0.33 also fixes the HTTP 400 from
langgraph-api 0.7+ when both configurable and context are present.
Bumped in two files:
- packages/runtime/package.json: 0.0.31 -> 0.0.33
- packages/sdk-js/package.json: 0.0.31 -> 0.0.33
Added @ag-ui/langgraph to minimumReleaseAgeExclude in .npmrc.
pnpm-lock.yaml regenerated.
Showcase auto-redeploys on merge via showcase_build.yml.
Add peer dependencies, export new components and hooks from package entry point, integrate RenderToolProvider into CopilotKitProvider, configure vitest and tsdown, add usage documentation.
Three V1 funnel events from the inspector — oss.inspector.banner_viewed,
oss.inspector.banner_clicked, oss.inspector.threads_tab_clicked — plus a
privacy panel for opt-out, a first-run console disclosure on inspector
mount and runtime startup, and inspector content added to the canonical
/telemetry docs page on main.
Inspector POSTs directly from the browser to telemetry.copilotkit.ai/ingest
(per ticket: URL is intentionally clearly named for transparency in DevTools).
Inline fetch POST in lib/telemetry.ts — no @copilotkit/shared dep on the
inspector, no dependency on any non-main branch.
Wire body shape (conservative; needs Ben confirmation):
POST https://telemetry.copilotkit.ai/ingest
{ event, properties: { ...caller, distinct_id, package }, ts }
If the lambda expects a richer envelope, update the single JSON.stringify
in lib/telemetry.ts.
Privacy invariants:
- Opt-out toggle short-circuits before any network call (verified by test).
- Properties are scoped to event metadata only — no message content, agent
state, prompts, completions, banner markdown. Negative test pins the wire.
- Anonymous distinct ID (UUID v4 in localStorage) set on inspector load and
propagated onto banner CTA links as ?posthog_distinct_id=<uuid> so the
destination site can posthog.alias() and close the
banner_viewed → banner_clicked → signup_attributed funnel. URL param
suppressed when opted out.
- Console disclosure on first inspector mount and runtime startup. Both
link to https://docs.copilotkit.ai/telemetry.
Plan gaps addressed:
- CTA name on banner_clicked: cta:'body'|'dismiss' (click location) plus
optional cta_label read defensively. Sam: confirm dismiss treatment.
- De-anon opt-out folded into the single toggle. Docs say so explicitly.
- banner_viewed dedup: per-instance Set<string> keyed by timestamp.
- EPIC consent / pixel review: out of scope for this PR; flagged at merge.
Deferred for V1.1:
- Wire body shape (Ben).
- Event-type allowlist for oss.inspector.* (Ben — oss-path-to-production).
- posthog_distinct_id URL-param key name (Ben/Tyler/website team).
Refs https://linear.app/copilotkit/issue/OSS-96
Closes the demo↔probe coverage gap for /demos/{interrupt-headless,
shared-state-read, tool-rendering-reasoning-chain} so every demo
under langgraph-python (the north-star integration) now has a D5
probe writing to its own PocketBase cell — not relying on cross-
demo umbrella records.
New probes (multi-turn, mirroring the agentic-chat structure):
- d5-interrupt-headless: exercises useHeadlessInterrupt — chip
prompt → backend interrupt(...) → app-surface popup → slot pick
→ resume → assistant confirmation. Distinct from gen-ui-interrupt
(which uses inline useInterrupt).
- d5-tool-rendering-reasoning-chain: combines reasoning-block slot
+ per-tool renderer (WeatherCard, FlightListCard) on the same
chat surface. Catches a regression in either side.
- d5-shared-state-read: recipe-editor demo (neutral default agent,
no tools) — verifies recipe-card form mounts AND agent reads
shared state across turns. Drops the dual-claim that
d5-shared-state.ts had on `shared-state-read` (now write-only).
Driver retry-once (e2e-deep.ts):
Probes that fail with a transient class (`goto-error` /
`conversation-error`) AND took ≥2s on the first attempt now retry
once before recording red. Persistent assertion-style failures
(sub-2s) and intentional aborts/feature-timeouts skip retry —
retrying a deterministic mismatch just burns clock and obscures
the signal. Cuts ~10× the dashboard flap rate.
Plumbing:
- D5FeatureType enum: +interrupt-headless, +tool-rendering-reasoning-chain.
- REGISTRY_TO_D5 (harness) + CATALOG_TO_D5_KEY (dashboard) mirror
the new mappings; d5-mapping-drift test enforces this.
- LGP manifest features + demos entries + constraints allowlist.
- feature-registry.json: +shared-state-read.
- aimock d5-all.json: +2 shared-state-read fixtures (interrupt-
headless + tool-rendering-reasoning-chain reuse existing fixtures
that already match their chip prompts).
Tests: 1588/1588 harness vitest green. validate-fixture-tool-surface
clean (282 fixtures × 627 demos, no drift). Two pre-existing test
fixes folded in — d5-gen-ui-interrupt assertion mock updated to
match the current evaluate-poll resume signal; conversation-runner
preFill ordering test now asserts the actual deferred-cascade
contract instead of a stricter pre-preFill ban that the runner
never enforced.
Known follow-up (not in this PR): auth.spec.ts test #5 ("signing
back in re-mounts a fresh chat surface") fails on Railway — second
sign-in's "Hello again" never produces an assistant response. Looks
like a react-core/v2 ref-handling regression on <CopilotKit>
unmount/remount; deserves its own focused investigation.
Other integrations may flip red on the new probes — that's
expected. We're treating LGP as the template; cross-integration
parity follows in a separate wave.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add to monorepo scope in release.config.json. Set version to 1.56.5,
correct ESM extensions in exports map, add check-types/publint/attw
scripts, align tsdown to ^0.20.3. Add react-native example glob to
pnpm-workspace.yaml. Regenerate lockfile preserving zod@3 and
langchain dependency versions.
## 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)
Reverts the example-app integration that was used for local end-to-end
testing of the inspector against an intelligence-backed runtime. The
example app is not part of the pnpm workspace, ships its own
package-lock.json, and pulls @copilotkit/* from the npm registry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The intelligence-backed example was a standalone npm-managed monorepo
pinned to published @copilotkit/runtime 1.56.3, so iterating on the
runtime against an Intelligence platform required publishing a release
or hand-linking. Pulling its two JS apps into the pnpm workspace lets
them resolve workspace:* and use whatever the local packages currently
build to.
Specific changes:
- Adds the example's app and bff to pnpm-workspace.yaml.
- Switches their @copilotkit/* deps to workspace:*; adds
@copilotkit/web-inspector as a workspace dep on the frontend so the
inspector can mount alongside the chat.
- Adds a small <Inspector /> React component that side-effect-imports
@copilotkit/web-inspector to register the custom element and assigns
the CopilotKit core via a ref (Lit elements expect properties, not
attributes, for complex values).
- Bumps the docker-compose image to the rc.16 composite, which is the
earliest published tag containing CopilotKit/Intelligence#144's
/api/_inspect/threads/:id/{events,state} endpoints.
- Drops the example's package-lock.json so npm and pnpm don't fight
over lockfiles in the workspace.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
Replaces the `/eval` PR comment trigger with a professional GitHub Check
Run button UX, and adds native (no-Docker) CI execution infrastructure.
### Check Run Button (Phase 1)
- **showcase_eval_check.yml** — creates a Check Run with "Run Showcase
Eval" action button on every PR open/push
- **showcase/eval-webhook/** — tiny Hono relay service on Railway that
receives `check_run.requested_action` webhooks, authenticates as devops
bot, and dispatches `showcase_eval.yml` via `workflow_dispatch`
- **showcase_eval.yml** — adds `workflow_dispatch` trigger with
`dispatch-gate` job, Check Run lifecycle updates (neutral → in_progress
→ completed with results), devops bot token for Checks API
### Native Execution (Phase 2)
- **`--ci` flag** on eval orchestrator — skips Docker lifecycle
(`up/down/isRunning/docker-inspect`), assumes services already running
- **ci-native-eval.sh** — standalone helper that installs deps, starts
`next dev --turbopack` + Python agents natively, health-waits, runs
`showcase eval --ci`
- **test_e2e-showcase-on-demand.yml** — fixed and extended with
`langgraph-python` support, agent-type detection (uvicorn vs
langgraph_cli), relaxed aimock_toggle.py requirement
### Setup required (post-merge)
1. Add `checks:write` permission to the copilotkit-devops-bot GitHub App
2. Deploy eval-webhook to Railway with app secrets
3. Configure GitHub App webhook URL to point to the Railway service
## Test plan
- [x] showcase-harness: 1480 tests pass
- [ ] CI green
- [ ] Deploy eval-webhook, verify `/health` endpoint
- [ ] Open test PR, verify Check Run appears with button
- [ ] Click button, verify eval triggers and Check Run updates
Hono web server that receives check_run.requested_action webhooks from
GitHub, authenticates as the devops bot, updates the Check Run to
in_progress, and dispatches showcase_eval.yml via workflow_dispatch.
Includes GHCR build workflow and pnpm workspace registration.
Picks up the router fix from CopilotKit/aimock#148 — `toolCallId` matchers
now only fire when the tool message is the *last* message in the request,
preventing stale tool_call_ids from history shadowing `userMessage`
matchers on new user turns.
Surfaced as: in beautiful-chat, clicking a second suggestion replayed the
prior chart's "Pie chart rendered above…" content fixture instead of
producing a new tool call. Once Railway rebuilds `ghcr.io/copilotkit/aimock:latest`
and restarts the service, demos will pick up the fix automatically.
- Refresh `pnpm-lock.yaml` resolutions (workspace `@copilotkit/runtime` devDep)
- Refresh `showcase/scripts/package-lock.json` to 1.16.4
- Bump the floor in `test_e2e-showcase-on-demand.yml` from `^1.14.3` → `^1.16.4`
so the `/test-aimock` PR-comment workflow always installs a build that
contains the fix
Picks up ag-ui-protocol/ag-ui#1578 — `import * as jsonpatch from
"fast-json-patch"` produced an empty namespace under Node native ESM
because fast-json-patch@3.x populates exports via Object.assign, which
the CJS→ESM named-export detector cannot see. Result: every STATE_DELTA
and ACTIVITY_DELTA event threw "applyPatch is not a function", and
LangGraph generative UI streams floods the console with the failure on
each patch.
0.0.53 switches to a default import so the emitted bundle works under
both ESM and CJS consumers. Bumped @ag-ui/core and @ag-ui/encoder in
lockstep since they share the release.
@types/react 19.2.x breaks recharts class component types with
"JSX element class does not support attributes because it does not
have a 'props' property." Pin the workspace-wide pnpm override and
the chat-with-your-data devDependency to 19.1.8.
Adds a `zodState` helper that attaches a `~standard.jsonSchema.input`
hook to Standard-Schema-compatible schemas (e.g. Zod). Without this,
Zod v4 fields carry `~standard.validate` + `vendor` only, so
LangGraph's `isStandardJSONSchema()` returns false and
`getJsonSchemaFromSchema` (called from `StateSchema.getJsonSchema`)
silently drops them from the graph's `output_schema`. AG-UI
`STATE_SNAPSHOT` events then filter the field out of the payload sent
to the frontend, even though the underlying thread state has it.
Wraps the internal `copilotkit` field in `copilotKitStateSchema` with
`zodState(...)` and exports the helper for user state schemas.
Bumps `@ag-ui/langgraph` to 0.0.30 and `@langchain/{core,langgraph}` /
`langchain` to the v1.1.41 / v1.2.9 / v1.3.4 line, which is the source
of the Zod v4 behavior this fix targets.
Recreates the sdk-js portion of #4320.
https://claude.ai/code/session_015B7RT1QxqyMmGDQYyaN7At
Restructure page to viewport-filling flex layout so table column
headers stick below the overlay toggle bar on scroll. Halve cell
padding, reduce column min-width, center UWCT/health badges and
links. Remove duplicate CellStatus from CommandCell (ComposedCell
HealthLayer handles it). Split stats bar out of sticky container
so it scrolls away naturally.
Needed for turnIndex/sequenceIndex fixture matching in D5 multi-turn
conversations. Updated in both packages/runtime (devDep) and
showcase/scripts (dep).
Add missing `commander` dependency to showcase-harness package.json
(imported in cli.ts but never declared). Add index signatures to
SmokeInput and ChatToolsInput interfaces in targets.ts so they satisfy
the `{ [k: string]: unknown }` constraint from the Zod `.passthrough()`
schemas used by the liveness and e2e-chat-tools drivers.
The monitoring/alerting service is a test harness (probes, assertions,
alerting), not an operations service. Rename the directory, package
name (@copilotkit/showcase-ops → @copilotkit/showcase-harness), all
internal references (Dockerfile, Prometheus metric prefix
showcase_ops_ → showcase_harness_, orchestrator log messages, probe
YAML nameExcludes, test fixtures), and regenerate pnpm-lock.yaml.
Wire protocol names (X-Ops-* headers) and shell-dashboard internal
API naming (OPS_BASE_URL, ops-api.ts) are intentionally unchanged —
they are stable contracts between sender and receiver.
6.0.1 requires vite ^8.0.0 but pnpm resolves vite 7.3.1, causing
ERR_PACKAGE_PATH_NOT_EXPORTED when vitest loads. 5.2.0 supports
vite ^4-8 and resolves the issue. Pre-existing on main.
Replaces the Angular-backed cpk-thread-list / cpk-thread-details custom
elements with native Lit implementations inside @copilotkit/web-inspector,
so React, Vanilla, and any other non-Angular consumer of the inspector
gets full functionality without pulling the Angular runtime. The
@copilotkit/web-inspector-angular package is deleted entirely, and the
Angular demo no longer calls defineInspectorElements.
Backend: adds GET /threads/:id/events and GET /threads/:id/state to the
runtime (in-memory runner path). The Intelligence path returns 501 with
a clear "not yet supported on this runtime" empty state — coordination
with the Intelligence team is tracked separately (CPK-7453).
Also guards attachToCore's getThreadStores call so consumers on an older
@copilotkit/core don't throw when assigning inspector.core, and drops
two unrelated showcase-whitelist lines that landed in
scripts/hooks/check-binaries.sh during a prior merge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- hooks.ts: keep both threads/clear and cpk-debug-events in RouteInfo
- use-threads.tsx: keep registerThreadStore effect + adopt main's
runtimeStatus gating for context dispatch
- use-threads.test.tsx: keep both our register/unregister test and
main's new runtimeConnectionStatus=Connected gating test
- scripts/hooks/check-binaries.sh: add shell-docs and shell-dojo
demo-content.json exclusions (main introduced these >1MB files without
updating the exclusion list)
- lefthook.yml, pnpm-lock.yaml: accept main's version
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Missed on the first pass — root package.json had a pnpm.overrides pin on
@copilotkit/license-verifier@0.0.1-a1 that forced the lockfile to keep the
old version even after packages/runtime + packages/shared dep bumps.