## What does this PR do? Adds the CopilotKit consumer side of ENT-1173 across Shared, Runtime, Core, Web Inspector, and the existing Shell Docs pages. - Defines and parses optional trusted Inspector metadata for identity, plan, license, action, usage, and expiry. Runtime proxies it through a private, failure-isolated route, and Core refreshes it without changing connection state. - Groups Inspector navigation into Threads, Agents, and Learning. Threads renders finite, unlimited, unknown, overage, and expiring usage states plus matching trusted plan or license actions. - Keeps explicit `threadEndpoints` as the only authority for Thread requests. Locked or absent capability states make no list, subscription, detail, message, event, or state calls. - Keeps the zero-thread video, three example Threads, detail tabs, and guided tour in empty and locked states. General Intelligence remains the default onboarding path; only trusted `team_self_hosted` metadata uses self-hosted onboarding. - Gives an active license with missing Runtime routes a short **Finish setting up Rich Threads** state. Users can copy a safe coding-agent prompt or open the public Runtime setup guide. The same copy control appears in that guide, and raw Markdown/LLM views include the full prompt. - Keeps finite usage green below 90%, orange from 90% to the limit, and red at or above the limit. At 90%, a trusted plan action changes from **Manage Your Plan** to a purple **Upgrade Your Plan** without changing its trusted URL, action kind, or telemetry contract. - Adds a deterministic 33-state loopback lab for CopilotKit developers. It has no production route or export, is absent from public docs and package metadata, and is excluded from the npm tarball. `Expiring Soon` is display-only; this PR does not enable the thread culler. Managed Enterprise receives no manage-plan action, and Team Self-Hosted receives no hosted plan action. Optional metadata and the additive expiry field remain compatible across mixed producer, Runtime, Core, and Inspector versions. A small Channels test-only change updates fetch mocks for current TypeScript types. It changes no Slack or Teams docs or runtime behavior. ## Related PRs and issues - Refs [ENT-1173](https://linear.app/copilotkit/issue/ENT-1173/ship-plg-ready-inspector-navigation-metadata-and-locked-threads) - Producer: [CopilotKit/Intelligence#696](https://github.com/CopilotKit/Intelligence/pull/696) ## Validation - `@copilotkit/web-inspector`: 20 files and 372 tests passed; typecheck and production build passed. - Shell Docs: 57 files and 383 tests passed; lint, typecheck, and production build passed. The build generated all 222 static pages. - Browser checks cover the copy-prompt flow, unchanged white **Manage Your Plan**, purple **Upgrade Your Plan**, orange 4,500/5,000 usage, and red 5,000/5,000 usage. - Independent review found no Critical or Important issues. - The broader Runtime, React Native, Channels, package-quality, compatibility, and Node-version checks from the prior pushed head remain green. ## Checklist - [x] I have read the [Contribution Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md) - [x] I updated the relevant documentation - [ ] "Allow edits by maintainers" is checked
CopilotKit - Shared
✨ Why CopilotKit?
- Minutes to integrate - Get started quickly with our CLI
- Framework agnostic - Works with React, Next.js, AGUI and more
- Production-ready UI - Use customizable components or build with headless UI
- Built-in security - Prompt injection protection
- Open source - Full transparency and community-driven
🧑💻 Real life use cases
Deploy deeply-integrated AI assistants & agents that work alongside your users inside your applications.
🖥️ Code Samples
Drop in these building blocks and tailor them to your needs.
Build with Headless APIs and Pre-Built Components
// Headless UI with full control
const { visibleMessages, appendMessage, setMessages, ... } = useCopilotChat();
// Pre-built components with deep customization options (CSS + pass custom sub-components)
<CopilotPopup
instructions={"You are assisting the user as best as you can. Answer in the best way possible given the data you have."}
labels={{ title: "Popup Assistant", initial: "Need any help?" }}
/>
// Frontend actions + generative UI, with full streaming support
useCopilotAction({
name: "appendToSpreadsheet",
description: "Append rows to the current spreadsheet",
parameters: [
{ name: "rows", type: "object[]", attributes: [{ name: "cells", type: "object[]", attributes: [{ name: "value", type: "string" }] }] }
],
render: ({ status, args }) => <Spreadsheet data={canonicalSpreadsheetData(args.rows)} />,
handler: ({ rows }) => setSpreadsheet({ ...spreadsheet, rows: [...spreadsheet.rows, ...canonicalSpreadsheetData(rows)] }),
});
Integrate In-App CoAgents with LangGraph
// Share state between app and agent
const { agentState } = useCoAgent({
name: "basic_agent",
initialState: { input: "NYC" }
});
// agentic generative UI
useCoAgentStateRender({
name: "basic_agent",
render: ({ state }) => <WeatherDisplay {...state.final_response} />,
});
// Human in the Loop (Approval)
useCopilotAction({
name: "email_tool",
parameters: [
{
name: "email_draft",
type: "string",
description: "The email content",
required: true,
},
],
renderAndWaitForResponse: ({ args, status, respond }) => {
return (
<EmailConfirmation
emailContent={args.email_draft || ""}
isExecuting={status === "executing"}
onCancel={() => respond?.({ approved: false })}
onSend={() =>
respond?.({
approved: true,
metadata: { sentAt: new Date().toISOString() },
})
}
/>
);
},
});
// intermediate agent state streaming (supports both LangGraph.js + LangGraph python)
const modifiedConfig = copilotKitCustomizeConfig(config, {
emitIntermediateState: [
{
stateKey: "outline",
tool: "set_outline",
toolArgument: "outline",
},
],
});
const response = await ChatOpenAI({ model: "gpt-4o" }).invoke(
messages,
modifiedConfig,
);
🏆 Featured Examples
Trusted Inspector metadata
@copilotkit/shared exports the versioned InspectorMetadataV1 contract and
parseInspectorMetadataV1() parser. A Copilot Runtime can use this contract to
send project and license context to the Inspector:
interface InspectorMetadataV1 {
readonly schemaVersion: 1;
readonly identity?: {
readonly organizationName: string;
readonly projectName: string;
};
readonly plan?: { readonly code: string; readonly label: string };
readonly license?: {
readonly state: "valid" | "none" | "expired" | "unknown";
};
readonly action?:
| { readonly kind: "manage_plan"; readonly url: string }
| { readonly kind: "renew"; readonly url: string }
| { readonly kind: "enable_intelligence"; readonly url: string };
readonly usage?: {
readonly used: number;
readonly limit:
| { readonly kind: "finite"; readonly value: number }
| { readonly kind: "unlimited" }
| { readonly kind: "unknown" };
readonly expiringSoonCount?: number;
};
}
Every optional module is independent. The parser drops an invalid identity,
plan, license, action, or usage module without hiding valid sibling
modules. It returns undefined when the top-level value is not a plain object
with schemaVersion: 1.
Action URLs are treated as trusted navigation only after parsing. They must use
HTTPS, or HTTP on localhost, 127.0.0.1, or [::1]; URLs with credentials, a
query string, or a fragment are rejected. Consumers use the accepted URL as
supplied and must not derive a destination from identity or plan values.
The optional usage.expiringSoonCount field lets V1 producers report a known
count. Older producers may omit it; absence remains valid V1 usage, while 0
is a known count and stays distinct from absence. The parser drops a malformed,
inherited, or accessor-backed expiry leaf without removing used, limit, or
valid sibling modules. Older V1 consumers ignore the additive field, so
producers and consumers do not need a V2 schema or lock-step deployment.
RuntimeInfo.inspectorMetadata?: boolean is the capability signal. Clients only
request the optional metadata route when a runtime reports
inspectorMetadata: true in its runtime-info response.
Documentation
To get started with CopilotKit, please check out the documentation.