thesys-c1-genui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNote: Refer to this SKILL.md file whenever there is any requirement for adding/editing functionality for C1.
注意:每当需要为C1添加/编辑功能时,请参考此SKILL.md文件。
Thesys C1 Generative UI Development
Thesys C1生成式UI开发
This skill provides comprehensive guidance for developing applications with the Thesys C1 API and GenUI SDK, enabling AI-powered Generative UI applications.
本技能提供了使用Thesys C1 API和GenUI SDK开发应用的全面指导,助力构建AI驱动的生成式UI应用。
What is Thesys C1?
什么是Thesys C1?
Thesys C1 is a Generative UI API that dynamically generates interactive UI components from natural language prompts. Unlike traditional AI that returns text/markdown, C1 generates live, interactive interfaces rendered through React components.
Thesys C1是一款生成式UI API,可通过自然语言提示动态生成交互式UI组件。与返回文本/Markdown的传统AI不同,C1生成的是可通过React组件渲染的实时交互式界面。
Key Features
核心特性
- Interactive Components: Forms, charts, tables, buttons that users can interact with
- Themeable: Consistent brand styling via
<ThemeProvider> - Real-time UI Streaming: Progressive rendering as responses generate
- OpenAI-Compatible API: Drop-in replacement for OpenAI SDKs
- Robust Error Handling: Graceful degradation with prop
onError
- 交互式组件:用户可交互的表单、图表、表格、按钮
- 可定制主题:通过实现统一的品牌样式
<ThemeProvider> - 实时UI流式传输:响应生成时逐步渲染
- 兼容OpenAI的API:可直接替代OpenAI SDK
- 强大的错误处理:通过属性实现优雅降级
onError
What Can You Build?
可构建的应用类型
- Analytics dashboards with dynamic charts
- Conversational AI agents with rich UI
- Internal tools and admin panels
- E-commerce flows with forms and product displays
- AI assistants like ChatGPT with Generative UI
- 带有动态图表的分析仪表板
- 拥有丰富UI的对话式AI代理
- 内部工具和管理面板
- 包含表单和产品展示的电商流程
- 带有生成式UI的类ChatGPT AI助手
Quickstart
快速开始
Prerequisites
前提条件
- Node.js 18+ or Python 3.8+
- Thesys API key from console.thesys.dev
- Install the required packages:
bash
npm install @thesysai/genui-sdk@latest @crayonai/react-ui@latest @crayonai/react-core@latest @crayonai/stream@latest openai@latest next@latest react@^19.0.0 react-dom@^19.0.0- Node.js 18+ 或 Python 3.8+
- 从console.thesys.dev获取Thesys API密钥
- 安装所需包:
bash
npm install @thesysai/genui-sdk@latest @crayonai/react-ui@latest @crayonai/react-core@latest @crayonai/stream@latest openai@latest next@latest react@^19.0.0 react-dom@^19.0.0Next.js Setup
Next.js 配置
bash
npx create-c1-app my-app
cd my-app
npm run devbash
npx create-c1-app my-app
cd my-app
npm run devPython (FastAPI) Setup
Python (FastAPI) 配置
bash
git clone https://github.com/thesysdev/template-c1-fastapi.git
cd template-c1-fastapi
pip install -r requirements.txt
uvicorn main:app --reloadbash
git clone https://github.com/thesysdev/template-c1-fastapi.git
cd template-c1-fastapi
pip install -r requirements.txt
uvicorn main:app --reloadIn another terminal for frontend:
在另一个终端启动前端:
npm install && npm run dev
Set your API key:
```bash
export THESYS_API_KEY=<your-api-key>npm install && npm run dev
设置API密钥:
```bash
export THESYS_API_KEY=<your-api-key>Core Components
核心组件
<C1Component>
- Render C1 Responses
<C1Component><C1Component>
- 渲染C1响应
<C1Component>The fundamental component that renders C1 DSL into a functional micro-frontend:
tsx
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
<ThemeProvider>
<C1Component
c1Response={response}
isStreaming={isLoading}
onAction={({ llmFriendlyMessage, humanFriendlyMessage }) => {
// Handle button clicks, form submissions
}}
updateMessage={(updatedResponse) => {
// Persist state changes to database
}}
/>
</ThemeProvider>这是将C1 DSL渲染为功能化微前端的基础组件:
tsx
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
<ThemeProvider>
<C1Component
c1Response={response}
isStreaming={isLoading}
onAction={({ llmFriendlyMessage, humanFriendlyMessage }) => {
// 处理按钮点击、表单提交
}}
updateMessage={(updatedResponse) => {
// 将状态变更持久化到数据库
}}
/>
</ThemeProvider><C1Chat>
- Full Conversational UI
<C1Chat><C1Chat>
- 完整对话式UI
<C1Chat>A batteries-included chat component with thread management:
tsx
import { C1Chat } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
<C1Chat
apiUrl="/api/chat"
agentName="My Assistant"
logoUrl="/logo.png"
formFactor="full-page" // or "side-panel"
/>这是一个内置线程管理的一站式聊天组件:
tsx
import { C1Chat } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
<C1Chat
apiUrl="/api/chat"
agentName="My Assistant"
logoUrl="/logo.png"
formFactor="full-page" // 或 "side-panel"
/>Key Differences
核心差异
| Feature | | |
|---|---|---|
| Render C1 DSL | ✅ | ✅ |
| Streaming | ✅ | ✅ |
| Forms & Actions | ✅ | ✅ |
| Message History | DIY | ✅ Built-in |
| Thread Management | DIY | ✅ Built-in |
| Chat UI | ❌ | ✅ |
| 特性 | | |
|---|---|---|
| 渲染C1 DSL | ✅ | ✅ |
| 流式传输 | ✅ | ✅ |
| 表单与操作 | ✅ | ✅ |
| 消息历史 | 需自行实现 | ✅ 内置 |
| 线程管理 | 需自行实现 | ✅ 内置 |
| 聊天UI | ❌ | ✅ |
How C1 Works
C1工作原理
The Flow
流程
- User sends prompt → Frontend
- Frontend calls backend → Your API
- Backend calls C1 API →
https://api.thesys.dev/v1/embed - C1 returns DSL → Backend
- Backend streams to frontend → Response
- renders UI → User sees interactive UI
<C1Component>
- 用户发送提示 → 前端
- 前端调用后端 → 你的API
- 后端调用C1 API →
https://api.thesys.dev/v1/embed - C1返回DSL → 后端
- 后端流式传输到前端 → 响应
- 渲染UI → 用户看到交互式UI
<C1Component>
Backend API Call
后端API调用
typescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
const response = await client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Show me a chart of sales data" }
],
stream: true,
});typescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
const response = await client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Show me a chart of sales data" }
],
stream: true,
});C1 Response Structure
C1响应结构
C1 responses use an XML-like structure:
xml
<thinking>Analyzing request...</thinking>
<content>
<!-- Interactive UI components -->
</content>
<artifact id="report-1">
<!-- Document content like slides/reports -->
</artifact>C1响应采用类XML结构:
xml
<thinking>Analyzing request...</thinking>
<content>
<!-- Interactive UI components -->
</content>
<artifact id="report-1">
<!-- Document content like slides/reports -->
</artifact>Supported Models
支持的模型
Stable Models:
c1/anthropic/claude-sonnet-4/v-20251230c1/openai/gpt-5/v-20251230
Experimental Models:
c1-exp/anthropic/claude-sonnet-4.5/v-20251230c1-exp/anthropic/claude-haiku-4.5/v-20251230
Artifact Model:
c1/artifact/v-20251230
稳定模型:
c1/anthropic/claude-sonnet-4/v-20251230c1/openai/gpt-5/v-20251230
实验性模型:
c1-exp/anthropic/claude-sonnet-4.5/v-20251230c1-exp/anthropic/claude-haiku-4.5/v-20251230
产物模型:
c1/artifact/v-20251230
Backend API Setup
后端API配置
Install Dependencies
安装依赖
bash
npm install openai @crayonai/streambash
npm install openai @crayonai/streamCreate Message Store
创建消息存储
typescript
// app/api/chat/messageStore.ts
import OpenAI from "openai";
export type DBMessage = OpenAI.Chat.ChatCompletionMessageParam & { id?: string };
const messagesStore: { [threadId: string]: DBMessage[] } = {};
export const getMessageStore = (threadId: string) => {
if (!messagesStore[threadId]) {
messagesStore[threadId] = [];
}
return {
addMessage: (message: DBMessage) => {
messagesStore[threadId].push(message);
},
getOpenAICompatibleMessageList: () => {
return messagesStore[threadId].map((m) => {
const { id, ...rest } = m;
return rest;
});
},
};
};typescript
// app/api/chat/messageStore.ts
import OpenAI from "openai";
export type DBMessage = OpenAI.Chat.ChatCompletionMessageParam & { id?: string };
const messagesStore: { [threadId: string]: DBMessage[] } = {};
export const getMessageStore = (threadId: string) => {
if (!messagesStore[threadId]) {
messagesStore[threadId] = [];
}
return {
addMessage: (message: DBMessage) => {
messagesStore[threadId].push(message);
},
getOpenAICompatibleMessageList: () => {
return messagesStore[threadId].map((m) => {
const { id, ...rest } = m;
return rest;
});
},
};
};Create Chat Endpoint
创建聊天端点
typescript
// app/api/chat/route.ts
import { NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
import { DBMessage, getMessageStore } from "./messageStore";
export async function POST(req: NextRequest) {
const { prompt, threadId, responseId } = await req.json() as {
prompt: DBMessage;
threadId: string;
responseId: string;
};
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
const messageStore = getMessageStore(threadId);
messageStore.addMessage(prompt);
const llmStream = await client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: messageStore.getOpenAICompatibleMessageList(),
stream: true,
});
const responseStream = transformStream(
llmStream,
(chunk) => chunk.choices[0].delta.content,
{
onEnd: ({ accumulated }) => {
const message = accumulated.filter(Boolean).join("");
messageStore.addMessage({
role: "assistant",
content: message,
id: responseId,
});
},
}
) as ReadableStream;
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
Connection: "keep-alive",
},
});
}typescript
// app/api/chat/route.ts
import { NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
import { DBMessage, getMessageStore } from "./messageStore";
export async function POST(req: NextRequest) {
const { prompt, threadId, responseId } = await req.json() as {
prompt: DBMessage;
threadId: string;
responseId: string;
};
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
const messageStore = getMessageStore(threadId);
messageStore.addMessage(prompt);
const llmStream = await client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: messageStore.getOpenAICompatibleMessageList(),
stream: true,
});
const responseStream = transformStream(
llmStream,
(chunk) => chunk.choices[0].delta.content,
{
onEnd: ({ accumulated }) => {
const message = accumulated.filter(Boolean).join("");
messageStore.addMessage({
role: "assistant",
content: message,
id: responseId,
});
},
}
) as ReadableStream;
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
Connection: "keep-alive",
},
});
}Integration Patterns
集成模式
C1 as Gateway LLM (Recommended)
C1作为网关LLM(推荐)
Replace your existing LLM endpoint with C1:
typescript
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed", // Change from OpenAI
apiKey: process.env.THESYS_API_KEY,
});
// Use existing tools and system prompts
const response = await client.beta.chat.completions.runTools({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: [...],
tools: existingTools,
stream: true,
});用C1替换你现有的LLM端点:
typescript
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed", // 从OpenAI修改为此地址
apiKey: process.env.THESYS_API_KEY,
});
// 使用现有工具和系统提示
const response = await client.beta.chat.completions.runTools({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: [...],
tools: existingTools,
stream: true,
});C1 as Presentation Layer
C1作为展示层
Generate text with your LLM, then visualize with C1:
typescript
// 1. Get text from your LLM
const textResponse = await yourLLM.generate(prompt);
// 2. Visualize with C1
const uiResponse = await c1Client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: [{ role: "user", content: textResponse }],
});用你的LLM生成文本,然后用C1可视化:
typescript
// 1. 从你的LLM获取文本
const textResponse = await yourLLM.generate(prompt);
// 2. 用C1可视化
const uiResponse = await c1Client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20251230",
messages: [{ role: "user", content: textResponse }],
});C1 as a Tool
C1作为工具
Expose C1 as a tool your agent can invoke:
typescript
const tools = [{
type: "function",
function: {
name: "generate_ui",
description: "Generate interactive UI for user",
parameters: {
type: "object",
properties: {
content: { type: "string", description: "Content to visualize" }
}
}
}
}];If the user wants to visualize their own data, refer to visualize-api-endpoint.md.
将C1暴露为你的代理可调用的工具:
typescript
const tools = [{
type: "function",
function: {
name: "generate_ui",
description: "Generate interactive UI for user",
parameters: {
type: "object",
properties: {
content: { type: "string", description: "Content to visualize" }
}
}
}
}];如果用户想要可视化自己的数据,请参考visualize-api-endpoint.md。
Additional References
附加参考
For detailed information on specific topics, see:
- Conversational UI & Persistence: State management, ,
useThreadManager, database persistenceuseThreadListManager - Custom Actions, Components & Thinking States: ,
c1_custom_actions, custom components,onAction, thinking statesuseC1State - Artifacts: Generating, rendering, editing, and exporting reports/presentations
- Customizations & Styling: , chart palettes, CSS overrides
<ThemeProvider> - Migration Guide: Step-by-step migration from text-based LLM to Generative UI
如需特定主题的详细信息,请查看:
- 对话式UI与持久化:状态管理、、
useThreadManager、数据库持久化useThreadListManager - 自定义操作、组件与思考状态:、
c1_custom_actions、自定义组件、onAction、思考状态useC1State - 产物:生成、渲染、编辑和导出报告/演示文稿
- 定制与样式:、图表调色板、CSS覆盖
<ThemeProvider> - 迁移指南:从基于文本的LLM迁移到生成式UI的分步指南
Resources
资源
- Documentation: https://docs.thesys.dev
- API Reference: https://docs.thesys.dev/api-reference/getting-started
- Examples: https://github.com/thesysdev/examples
- Discord Community: https://discord.gg/Pbv5PsqUSv