Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/build-js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,15 @@ jobs:
with:
node-version: 20
cache: pnpm
cache-dependency-path: "examples/**/pnpm-lock.yaml"
cache-dependency-path: |
pnpm-lock.yaml
examples/**/pnpm-lock.yaml

- name: Install local example dependency build tools
run: pnpm install --frozen-lockfile --filter @openuidev/copilotkit --ignore-scripts

- name: Build local example dependencies
run: pnpm --filter @openuidev/copilotkit build

- name: Install dependencies
run: pnpm examples:install
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish-npm-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
required: true
type: choice
options:
- copilotkit
- assistant-ui
- react-ui
- react-headless
Expand Down
33 changes: 31 additions & 2 deletions docs/app/(home)/integrations/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ const integrationCatalog: Integration[] = [
howItWorks:
"Each shadcn component is registered with defineComponent and a Zod prop schema. createLibrary produces both the prompt vocabulary and the renderer mapping used by the example chat app.",
links: [
{ label: "Integration guide", href: "/docs/openui-lang/examples/design-systems/shadcn", kind: "Guide" },
{
label: "Integration guide",
href: "/docs/openui-lang/examples/design-systems/shadcn",
kind: "Guide",
},
exampleLink("shadcn-chat"),
{ label: "shadcn/ui", href: "https://ui.shadcn.com", kind: "Website" },
],
Expand Down Expand Up @@ -248,6 +252,23 @@ const integrationCatalog: Integration[] = [
},
],
},
{
slug: "copilotkit",
name: "CopilotKit",
logo: "/brand-icons/copilotkit-dark.svg",
category: "frontend-platforms",
type: "Agentic application framework",
summary:
"Render streaming OpenUI programs inside CopilotKit v2 tool calls while CopilotKit retains its chat and agent lifecycle.",
howItWorks:
"The @openuidev/copilotkit package registers matched frontend and human-in-the-loop tools, generates model instructions from the rendered component library, streams partial OpenUI Lang, and routes follow-ups or form submissions through CopilotKit's supported run and response APIs.",
install: "npm install @openuidev/copilotkit @copilotkit/react-core",
links: [
...packageLinks("@openuidev/copilotkit", "copilotkit", "/docs/api-reference/copilotkit"),
exampleLink("frontend-platforms/copilotkit", "Runnable example"),
{ label: "CopilotKit", href: "https://docs.copilotkit.ai", kind: "Website" },
],
},
{
slug: "ag-ui",
name: "AG-UI",
Expand Down Expand Up @@ -451,7 +472,15 @@ const popularityOrder: Record<IntegrationCategoryId, string[]> = {
"google-adk",
],
"design-systems": ["shadcn-ui", "material-ui", "handsontable", "react-email"],
"frontend-platforms": ["vue", "svelte", "react-native", "lynx", "assistant-ui", "open-webui"],
"frontend-platforms": [
"vue",
"svelte",
"react-native",
"lynx",
"assistant-ui",
"copilotkit",
"open-webui",
],
};

export const integrationBySlug = new Map(integrations.map((item) => [item.slug, item]));
Expand Down
190 changes: 190 additions & 0 deletions docs/content/docs/api-reference/copilotkit.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
title: "@openuidev/copilotkit"
description: API reference for rendering OpenUI Lang tool calls in CopilotKit v2 applications.
---

Use this package when CopilotKit owns the chat surface, agent, transport, and tool lifecycle and
OpenUI should render streaming, interactive interfaces inside tool calls.

## Install

```bash tab="pnpm" tab-group="pkg"
pnpm add @openuidev/copilotkit @copilotkit/react-core @openuidev/react-ui @openuidev/react-lang @openuidev/react-headless react react-dom zod zustand@^4.5.5
```

```bash tab="bun" tab-group="pkg"
bun add @openuidev/copilotkit @copilotkit/react-core @openuidev/react-ui @openuidev/react-lang @openuidev/react-headless react react-dom zod zustand@^4.5.5
```

```bash tab="yarn" tab-group="pkg"
yarn add @openuidev/copilotkit @copilotkit/react-core @openuidev/react-ui @openuidev/react-lang @openuidev/react-headless react react-dom zod zustand@^4.5.5
```

```bash tab="npm" tab-group="pkg"
npm install @openuidev/copilotkit @copilotkit/react-core @openuidev/react-ui @openuidev/react-lang @openuidev/react-headless react react-dom zod zustand@^4.5.5
```

Import both style sheets once:

```css
@import "@copilotkit/react-core/v2/styles.css";
@import "@openuidev/react-ui/layered/styles/index.css";
```

## `openuiIntegration`

The default integration combines CopilotKit v2 tools and model instructions generated from the
same `openuiChatLibrary` component vocabulary:

```ts
interface OpenUIIntegration {
frontendTools: [ReactFrontendTool<OpenUIToolArgs>];
humanInTheLoop: [ReactHumanInTheLoop<OpenUIToolArgs>];
instructions: string;
toolNames: {
present: string;
prompt: string;
};
}

const openuiIntegration: OpenUIIntegration;
```

Mount `OpenUIProvider` inside the CopilotKit provider. It registers both tools through CopilotKit's
hooks and adds the instructions to agent context:

```tsx
"use client";

import { CopilotChat, CopilotKit } from "@copilotkit/react-core/v2";
import { OpenUIProvider } from "@openuidev/copilotkit";

export function Chat() {
return (
<CopilotKit runtimeUrl="/api/copilotkit">
<OpenUIProvider />
<CopilotChat />
</CopilotKit>
);
}
```

The hook-based registration is required for `prompt_openui`: `useHumanInTheLoop` installs the
pending response handler that resolves when the OpenUI form calls CopilotKit's `respond` function.

| Tool | CopilotKit type | Behavior |
| :--------------- | :--------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `present_openui` | frontend tool | Renders complete interfaces. Optional follow-up and list actions add a user message and start exactly one CopilotKit agent run. `followUp` is disabled. |
| `prompt_openui` | human-in-the-loop tool | Waits for a required `@ToAssistant` form or choice action, responds once with the action and form state, then lets CopilotKit continue the current workflow. |

## `createOpenUIIntegration(options)`

Creates aligned tools and instructions for a custom library, tool names, renderer, or prompt
configuration.

```ts
interface CreateOpenUIIntegrationOptions extends OpenUIToolUIOptions {
promptOptions?: PromptOptions;
presentToolName?: string;
promptToolName?: string;
presentDescription?: string;
promptDescription?: string;
preamble?: string;
additionalRules?: string[];
agentId?: string;
available?: boolean;
}

function createOpenUIIntegration(options?: CreateOpenUIIntegrationOptions): OpenUIIntegration;
```

```ts
import { createOpenUIIntegration } from "@openuidev/copilotkit";
import { library } from "./library";

const openui = createOpenUIIntegration({
library,
presentToolName: "show_panel",
promptToolName: "ask_panel",
agentId: "support-agent",
});
```

Pass a custom result to the provider:

```tsx
<OpenUIProvider integration={openui} />
```

The factory applies `agentId` and `available` to both registrations. Display and prompt tools must
use different, non-empty names.

## Renderer APIs

```ts
function OpenUIContent(props: OpenUIContentProps): React.ReactNode;
function OpenUIPresent(props: OpenUIPresentProps): React.ReactNode;
function OpenUIPrompt(props: OpenUIPromptProps): React.ReactNode;

function createOpenUIPresent(options?: CreateOpenUIPresentOptions): ReactFrontendTool["render"];
function createOpenUIPrompt(options?: OpenUIToolUIOptions): ReactHumanInTheLoop["render"];
```

Shared configuration:

```ts
interface OpenUIToolUIOptions {
library?: Library;
rendererProps?: OpenUIRendererProps;
theme?: ThemeProps;
disableThemeProvider?: boolean;
ErrorFallback?: OpenUIErrorFallback | null;
onError?: (errors: OpenUIError[]) => void;
}
```

`OpenUIContent` wraps the OpenUI `Renderer` in the light `ThemeProvider` by default. Set
`disableThemeProvider: true` when the host already supplies an OpenUI theme. Parser errors may be
transient while the `ui` tool argument streams, so the default fallback appears only after
streaming finishes.

`OpenUIPresent` converts `FollowUpBlock` and optional list-item `@ToAssistant` actions into a user
message followed by `copilotkit.runAgent({ agent })`. A per-renderer gate prevents double clicks
from starting duplicate turns. `@OpenUrl` actions open in a new isolated tab.

`OpenUIPrompt` calls the CopilotKit `respond` function once for a terminal `@ToAssistant` action.
Its JSON result contains the action type, message, parameters, optional form name, and form state.
Replayed tool calls use the saved form state as the renderer's initial state.

## Instruction APIs

```ts
function createOpenUIInstructions(options?: CreateOpenUIInstructionsOptions): string;
function useOpenUIInstructions(options?: UseOpenUIInstructionsOptions): void;
function OpenUIInstructions(options: UseOpenUIInstructionsOptions): null;

const openuiInstructions: string;
```

The generated instructions tell the model when to use each tool, include the selected library's
OpenUI Lang prompt, and keep display-only and required-input contracts distinct.

`OpenUIInstructions` uses CopilotKit's `useAgentContext` hook. This keeps the OpenUI component
vocabulary in the agent run without importing a React component library into a server-only route.

## Exports

| Export | Description |
| :-------------------------------------- | :--------------------------------------------------------------- |
| `openuiIntegration` | Default aligned frontend tools, human tools, and instructions |
| `createOpenUIIntegration` | Integration factory for custom libraries, names, and agent scope |
| `OpenUIProvider` | Hook-based tool and instruction registration inside `CopilotKit` |
| `openuiInstructions` | Default generated model instructions |
| `createOpenUIInstructions` | Instruction factory |
| `OpenUIInstructions` | Component that registers instructions through `useAgentContext` |
| `useOpenUIInstructions` | Hook form of `OpenUIInstructions` |
| `OpenUIContent` | OpenUI renderer wrapper for streamed tool arguments |
| `OpenUIPresent` / `createOpenUIPresent` | Frontend-tool renderer and factory |
| `OpenUIPrompt` / `createOpenUIPrompt` | Human-in-the-loop renderer and factory |
| `parseOpenUIActionResult` | Safe parser for replayed CopilotKit human-tool results |
| `DefaultOpenUIErrorFallback` | Default post-stream renderer error message |
7 changes: 7 additions & 0 deletions docs/content/docs/api-reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ The OpenUI SDK is split into packages that build on each other:

- **`@openuidev/assistant-ui`** — OpenUI tool renderers, model instructions, and toolkit wiring for applications built with assistant-ui. The core integration supports any assistant-ui runtime; an optional `/ai-sdk` subpath adds Vercel AI SDK continuation behavior.

- **`@openuidev/copilotkit`** — OpenUI frontend-tool and human-in-the-loop renderers for CopilotKit v2. CopilotKit owns the chat shell and agent lifecycle while OpenUI renders streamed tool arguments and returns user actions.

- **`@openuidev/langchain`** — LangChain and LangGraph integration primitives for transforming protocol-v2 agent streams into AG-UI events and relaying them to an OpenUI frontend over Web-standard Server-Sent Events.

- **`@openuidev/react-email`** — Pre-built email component library and prompt options for model-generated emails that can be rendered to HTML with React Email.
Expand All @@ -38,6 +40,7 @@ The OpenUI SDK is split into packages that build on each other:
| Chat state and streaming without prebuilt UI | [`@openuidev/react-headless`](/docs/api-reference/react-headless) |
| A ready-made React chat surface | [`@openuidev/react-ui`](/docs/api-reference/react-ui) |
| OpenUI tool rendering in an assistant-ui application | [`@openuidev/assistant-ui`](/docs/api-reference/assistant-ui) |
| OpenUI tool rendering in a CopilotKit v2 application | [`@openuidev/copilotkit`](/docs/api-reference/copilotkit) |
| A LangChain or LangGraph agent connected to an OpenUI frontend | [`@openuidev/langchain`](/docs/api-reference/langchain) |
| Model-generated emails | [`@openuidev/react-email`](/docs/api-reference/react-email) |
| Vue integration | [`@openuidev/vue-lang`](https://github.com/thesysdev/openui/tree/main/packages/vue-lang) |
Expand Down Expand Up @@ -71,6 +74,10 @@ The OpenUI SDK is split into packages that build on each other:
Tool renderers, toolkit and instruction factories, interactive form handling, and optional
runtime-specific continuation helpers for assistant-ui applications.
</Card>
<Card title="@openuidev/copilotkit" href="/docs/api-reference/copilotkit">
Frontend and human-in-the-loop tools, streaming OpenUI renderers, aligned model instructions,
and action continuation for CopilotKit v2 applications.
</Card>
<Card title="@openuidev/langchain" href="/docs/api-reference/langchain">
LangGraph stream transformation, stateless run helpers, and AG-UI SSE relay APIs for OpenUI
frontends.
Expand Down
3 changes: 2 additions & 1 deletion docs/content/docs/api-reference/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"cli",
"devtools",
"langchain",
"assistant-ui"
"assistant-ui",
"copilotkit"
]
}
2 changes: 2 additions & 0 deletions examples/frontend-platforms/copilotkit/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4.1-mini
4 changes: 4 additions & 0 deletions examples/frontend-platforms/copilotkit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.env
.env.local
.next
node_modules
34 changes: 34 additions & 0 deletions examples/frontend-platforms/copilotkit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# OpenUI with CopilotKit

A runnable Next.js example showing `@openuidev/copilotkit` inside the CopilotKit v2 chat shell.

CopilotKit owns the agent, runtime endpoint, chat UI, streaming lifecycle, and follow-up runs. The OpenUI package contributes model instructions, a frontend display tool, a human-in-the-loop prompt tool, and renderers for the streamed `ui` argument.

## Run it

```bash
pnpm install --ignore-workspace
cp .env.example .env.local
```

Set `OPENAI_API_KEY` in `.env.local`. You can also change `OPENAI_MODEL`, which defaults to
`gpt-4.1-mini`. Then run:

```bash
pnpm dev
```

Open [http://localhost:3000](http://localhost:3000).

## Acceptance prompts

Paste these prompts into the chat to exercise each integration path:

1. Ask for a quarterly revenue comparison to render a chart and follow-up suggestions.
2. Click a follow-up to add one user message and start one new CopilotKit agent run.
3. Ask for event registration to render a human-in-the-loop form, enter values, and submit it once.
4. Ask for project plans to render a table with an optional list-item drill-down action.

The client mounts `OpenUIProvider` inside `CopilotKit`. That component registers the display tool,
the interactive human-in-the-loop handler, and the matching model vocabulary through CopilotKit's
v2 hooks. The server route stays focused on the CopilotKit runtime and model.
9 changes: 9 additions & 0 deletions examples/frontend-platforms/copilotkit/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
import { defineConfig, globalIgnores } from "eslint/config";

export default defineConfig([
...nextVitals,
...nextTs,
globalIgnores([".next/**", "next-env.d.ts"]),
]);
6 changes: 6 additions & 0 deletions examples/frontend-platforms/copilotkit/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
9 changes: 9 additions & 0 deletions examples/frontend-platforms/copilotkit/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { NextConfig } from "next";
import path from "node:path";

const nextConfig: NextConfig = {
turbopack: { root: path.resolve(process.cwd(), "../../..") },
transpilePackages: ["@openuidev/copilotkit"],
};

export default nextConfig;
Loading
Loading