thesys-c1-genui

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Note: 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
    onError
    prop
  • 交互式组件:用户可交互的表单、图表、表格、按钮
  • 可定制主题:通过
    <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.0

Next.js Setup

Next.js 配置

bash
npx create-c1-app my-app
cd my-app
npm run dev
bash
npx create-c1-app my-app
cd my-app
npm run dev

Python (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 --reload
bash
git clone https://github.com/thesysdev/template-c1-fastapi.git
cd template-c1-fastapi
pip install -r requirements.txt
uvicorn main:app --reload

In 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>
- 渲染C1响应

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>
- 完整对话式UI

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
<C1Component>
<C1Chat>
Render C1 DSL
Streaming
Forms & Actions
Message HistoryDIY✅ Built-in
Thread ManagementDIY✅ Built-in
Chat UI

特性
<C1Component>
<C1Chat>
渲染C1 DSL
流式传输
表单与操作
消息历史需自行实现✅ 内置
线程管理需自行实现✅ 内置
聊天UI

How C1 Works

C1工作原理

The Flow

流程

  1. User sends prompt → Frontend
  2. Frontend calls backend → Your API
  3. Backend calls C1 API
    https://api.thesys.dev/v1/embed
  4. C1 returns DSL → Backend
  5. Backend streams to frontend → Response
  6. <C1Component>
    renders UI
    → User sees interactive UI
  1. 用户发送提示 → 前端
  2. 前端调用后端 → 你的API
  3. 后端调用C1 API
    https://api.thesys.dev/v1/embed
  4. C1返回DSL → 后端
  5. 后端流式传输到前端 → 响应
  6. <C1Component>
    渲染UI
    → 用户看到交互式UI

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-20251230
  • c1/openai/gpt-5/v-20251230
Experimental Models:
  • c1-exp/anthropic/claude-sonnet-4.5/v-20251230
  • c1-exp/anthropic/claude-haiku-4.5/v-20251230
Artifact Model:
  • c1/artifact/v-20251230

稳定模型:
  • c1/anthropic/claude-sonnet-4/v-20251230
  • c1/openai/gpt-5/v-20251230
实验性模型:
  • c1-exp/anthropic/claude-sonnet-4.5/v-20251230
  • c1-exp/anthropic/claude-haiku-4.5/v-20251230
产物模型:
  • c1/artifact/v-20251230

Backend API Setup

后端API配置

Install Dependencies

安装依赖

bash
npm install openai @crayonai/stream
bash
npm install openai @crayonai/stream

Create 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
    ,
    useThreadListManager
    , database persistence
  • Custom Actions, Components & Thinking States:
    c1_custom_actions
    ,
    onAction
    , custom components,
    useC1State
    , thinking states
  • Artifacts: Generating, rendering, editing, and exporting reports/presentations
  • Customizations & Styling:
    <ThemeProvider>
    , chart palettes, CSS overrides
  • Migration Guide: Step-by-step migration from text-based LLM to Generative UI

如需特定主题的详细信息,请查看:
  • 对话式UI与持久化:状态管理、
    useThreadManager
    useThreadListManager
    、数据库持久化
  • 自定义操作、组件与思考状态
    c1_custom_actions
    onAction
    、自定义组件、
    useC1State
    、思考状态
  • 产物:生成、渲染、编辑和导出报告/演示文稿
  • 定制与样式
    <ThemeProvider>
    、图表调色板、CSS覆盖
  • 迁移指南:从基于文本的LLM迁移到生成式UI的分步指南

Resources

资源