thesys-generative-ui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTheSys Generative UI Integration
TheSys生成式UI集成
Complete skill for building AI-powered interfaces with TheSys C1 Generative UI API. Convert LLM responses into streaming, interactive React components.
通过TheSys C1生成式UI API构建AI驱动界面的完整指南。将LLM响应转换为流式交互式React组件。
What is TheSys C1?
什么是TheSys C1?
TheSys C1 is a Generative UI API that transforms Large Language Model (LLM) responses into live, interactive React components instead of plain text. Rather than displaying walls of text, your AI applications can stream forms, charts, tables, search results, and custom UI elements in real-time.
TheSys C1是一款生成式UI API,可将大语言模型(LLM)的响应转换为实时交互式React组件,而非纯文本。您的AI应用无需展示大量纯文本,而是可以实时流式传输表单、图表、表格、搜索结果和自定义UI元素。
Key Innovation
核心创新
Traditional LLM applications return text that developers must manually convert into UI:
LLM → Text Response → Developer Parses → Manual UI Code → DisplayTheSys C1 eliminates this manual step:
LLM → C1 API → Interactive React Components → Display传统LLM应用返回文本,开发者必须手动将其转换为UI:
LLM → 文本响应 → 开发者解析 → 手动编写UI代码 → 展示TheSys C1省去了这一手动步骤:
LLM → C1 API → 交互式React组件 → 展示Real-World Impact
实际应用效果
- 83% more engaging - Users prefer interactive components over text walls
- 10x faster development - No manual text-to-UI conversion
- 80% cheaper - Reduced development time and maintenance
- Production-ready - Used by teams building AI-native products
- 互动性提升83% - 用户更倾向于使用交互式组件而非纯文本内容
- 开发速度提升10倍 - 无需手动将文本转换为UI
- 成本降低80% - 减少开发时间与维护成本
- 可用于生产环境 - 已被开发AI原生产品的团队采用
When to Use This Skill
适用场景
Use this skill when building:
-
Chat Interfaces with Rich UI
- Conversational interfaces that need more than text
- Customer support chatbots with forms and actions
- AI assistants that show data visualizations
-
Data Visualization Applications
- Analytics dashboards with AI-generated charts
- Business intelligence tools with dynamic tables
- Search interfaces with structured results
-
Dynamic Form Generation
- E-commerce product configurators
- Multi-step workflows driven by AI
- Data collection with intelligent forms
-
AI Copilots and Assistants
- Developer tools with code snippets and docs
- Educational platforms with interactive lessons
- Research tools with citations and references
-
Search and Discovery
- Semantic search with structured results
- Document analysis with highlighted findings
- Knowledge bases with interactive answers
在以下场景中使用本指南:
-
具备丰富UI的聊天界面
- 不满足于纯文本的对话式界面
- 带有表单和操作的客户支持聊天机器人
- 展示数据可视化的AI助手
-
数据可视化应用
- 带有AI生成图表的分析仪表盘
- 具备动态表格的商业智能工具
- 带有结构化结果的搜索界面
-
动态表单生成
- 电商产品配置器
- AI驱动的多步骤工作流
- 智能数据收集表单
-
AI copilots与助手
- 带有代码片段和文档的开发者工具
- 具备交互式课程的教育平台
- 带有引用和参考文献的研究工具
-
搜索与发现
- 带有结构化结果的语义搜索
- 带有高亮结果的文档分析
- 带有交互式答案的知识库
This Skill Prevents These Errors
本指南可避免的错误
- ❌ Empty agent responses from incorrect streaming setup
- ❌ Models ignoring system prompts due to message array issues
- ❌ Version compatibility errors between SDK and API
- ❌ Themes not applying without ThemeProvider
- ❌ Streaming failures from improper response transformation
- ❌ Tool calling bugs from invalid Zod schemas
- ❌ Thread state loss from missing persistence
- ❌ CSS conflicts from import order issues
- ❌ TypeScript errors from outdated type definitions
- ❌ CORS failures from missing headers
- ❌ Rate limit crashes without retry logic
- ❌ Authentication token errors from environment issues
- ❌ 流式传输设置错误导致的Agent空响应
- ❌ 消息数组问题导致模型忽略系统提示
- ❌ SDK与API版本不兼容错误
- ❌ 未使用ThemeProvider导致主题不生效
- ❌ 响应转换不当导致的流式传输失败
- ❌ Zod schema无效导致的工具调用错误
- ❌ 缺少持久化导致的线程状态丢失
- ❌ 导入顺序问题导致的CSS冲突
- ❌ 类型定义过时导致的TypeScript错误
- ❌ 缺少请求头导致的CORS失败
- ❌ 无重试逻辑导致的速率限制崩溃
- ❌ 环境配置问题导致的认证令牌错误
Quick Start by Framework
按框架快速开始
Vite + React Setup
Vite + React 配置
Most flexible setup for custom backends (your preferred stack).
最灵活的配置,适用于自定义后端(您偏好的技术栈)。
1. Install Dependencies
1. 安装依赖
bash
npm install @thesysai/genui-sdk @crayonai/react-ui @crayonai/react-core @crayonai/stream
npm install openai zodbash
npm install @thesysai/genui-sdk @crayonai/react-ui @crayonai/react-core @crayonai/stream
npm install openai zod2. Create Chat Component
2. 创建聊天组件
File:
src/App.tsxtypescript
import "@crayonai/react-ui/styles/index.css";
import { ThemeProvider, C1Component } from "@thesysai/genui-sdk";
import { useState } from "react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
const [c1Response, setC1Response] = useState("");
const [question, setQuestion] = useState("");
const makeApiCall = async (query: string) => {
setIsLoading(true);
setC1Response("");
try {
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt: query }),
});
const data = await response.json();
setC1Response(data.response);
} catch (error) {
console.error("Error:", error);
} finally {
setIsLoading(false);
}
};
return (
<div className="container">
<h1>AI Assistant</h1>
<form onSubmit={(e) => {
e.preventDefault();
makeApiCall(question);
}}>
<input
type="text"
value={question}
onChange={(e) => setQuestion(e.target.value)}
placeholder="Ask me anything..."
/>
<button type="submit" disabled={isLoading}>
{isLoading ? "Processing..." : "Send"}
</button>
</form>
{c1Response && (
<ThemeProvider>
<C1Component
c1Response={c1Response}
isStreaming={isLoading}
updateMessage={(message) => setC1Response(message)}
onAction={({ llmFriendlyMessage }) => {
if (!isLoading) {
makeApiCall(llmFriendlyMessage);
}
}}
/>
</ThemeProvider>
)}
</div>
);
}文件:
src/App.tsxtypescript
import "@crayonai/react-ui/styles/index.css";
import { ThemeProvider, C1Component } from "@thesysai/genui-sdk";
import { useState } from "react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
const [c1Response, setC1Response] = useState("");
const [question, setQuestion] = useState("");
const makeApiCall = async (query: string) => {
setIsLoading(true);
setC1Response("");
try {
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt: query }),
});
const data = await response.json();
setC1Response(data.response);
} catch (error) {
console.error("Error:", error);
} finally {
setIsLoading(false);
}
};
return (
<div className="container">
<h1>AI Assistant</h1>
<form onSubmit={(e) => {
e.preventDefault();
makeApiCall(question);
}}>
<input
type="text"
value={question}
onChange={(e) => setQuestion(e.target.value)}
placeholder="Ask me anything..."
/>
<button type="submit" disabled={isLoading}>
{isLoading ? "Processing..." : "Send"}
</button>
</form>
{c1Response && (
<ThemeProvider>
<C1Component
c1Response={c1Response}
isStreaming={isLoading}
updateMessage={(message) => setC1Response(message)}
onAction={({ llmFriendlyMessage }) => {
if (!isLoading) {
makeApiCall(llmFriendlyMessage);
}
}}
/>
</ThemeProvider>
)}
</div>
);
}3. Configure Backend API (Express Example)
3. 配置后端API(Express示例)
typescript
import express from "express";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
const app = express();
app.use(express.json());
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
app.post("/api/chat", async (req, res) => {
const { prompt } = req.body;
const stream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930", // or any C1-compatible model
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: prompt },
],
stream: true,
});
// Transform OpenAI stream to C1 response
const c1Stream = transformStream(stream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
});
res.json({ response: await streamToString(c1Stream) });
});
async function streamToString(stream: ReadableStream) {
const reader = stream.getReader();
let result = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
result += value;
}
return result;
}
app.listen(3000);typescript
import express from "express";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
const app = express();
app.use(express.json());
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
app.post("/api/chat", async (req, res) => {
const { prompt } = req.body;
const stream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930", // 或任何兼容C1的模型
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: prompt },
],
stream: true,
});
// 将OpenAI流转换为C1响应
const c1Stream = transformStream(stream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
});
res.json({ response: await streamToString(c1Stream) });
});
async function streamToString(stream: ReadableStream) {
const reader = stream.getReader();
let result = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
result += value;
}
return result;
}
app.listen(3000);Next.js App Router Setup
Next.js App Router 配置
Most popular framework, full-stack with API routes.
最受欢迎的框架,全栈式API路由支持。
1. Install Dependencies
1. 安装依赖
bash
npm install @thesysai/genui-sdk @crayonai/react-ui @crayonai/react-core
npm install openaibash
npm install @thesysai/genui-sdk @crayonai/react-ui @crayonai/react-core
npm install openai2. Create Chat Page Component
2. 创建聊天页面组件
File:
app/page.tsxtypescript
"use client";
import { C1Chat } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
export default function Home() {
return (
<div className="min-h-screen">
<C1Chat apiUrl="/api/chat" />
</div>
);
}文件:
app/page.tsxtypescript
"use client";
import { C1Chat } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
export default function Home() {
return (
<div className="min-h-screen">
<C1Chat apiUrl="/api/chat" />
</div>
);
}3. Create API Route Handler
3. 创建API路由处理程序
File:
app/api/chat/route.tstypescript
import { NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
export async function POST(req: NextRequest) {
const { prompt } = await req.json();
const stream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{ role: "system", content: "You are a helpful AI assistant." },
{ role: "user", content: prompt },
],
stream: true,
});
// Transform to C1-compatible stream
const responseStream = transformStream(stream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
}) as ReadableStream<string>;
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
}That's it! You now have a working Generative UI chat interface.
文件:
app/api/chat/route.tstypescript
import { NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
export async function POST(req: NextRequest) {
const { prompt } = await req.json();
const stream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{ role: "system", content: "You are a helpful AI assistant." },
{ role: "user", content: prompt },
],
stream: true,
});
// 转换为兼容C1的流
const responseStream = transformStream(stream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
}) as ReadableStream<string>;
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
}完成! 您现在拥有一个可运行的生成式UI聊天界面。
Cloudflare Workers + Static Assets Setup
Cloudflare Workers + 静态资源 配置
Your stack: Workers backend with Vite+React frontend.
技术栈:Workers后端 + Vite+React前端。
1. Create Worker Backend (Hono)
1. 创建Worker后端(Hono)
File:
backend/src/index.tstypescript
import { Hono } from "hono";
import { cors } from "hono/cors";
const app = new Hono();
app.use("/*", cors());
app.post("/api/chat", async (c) => {
const { prompt } = await c.req.json();
// Use Cloudflare Workers AI or proxy to OpenAI
const response = await fetch("https://api.thesys.dev/v1/embed/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${c.env.THESYS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: prompt },
],
stream: false, // or handle streaming
}),
});
const data = await response.json();
return c.json(data);
});
export default app;文件:
backend/src/index.tstypescript
import { Hono } from "hono";
import { cors } from "hono/cors";
const app = new Hono();
app.use("/*", cors());
app.post("/api/chat", async (c) => {
const { prompt } = await c.req.json();
// 使用Cloudflare Workers AI或代理到OpenAI
const response = await fetch("https://api.thesys.dev/v1/embed/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${c.env.THESYS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: prompt },
],
stream: false, // 或处理流式传输
}),
});
const data = await response.json();
return c.json(data);
});
export default app;2. Frontend Setup (Same as Vite+React)
2. 前端配置(与Vite+React相同)
Use the Vite+React example above, but configure API calls to your Worker endpoint.
使用上述Vite+React示例,但将API调用配置为指向您的Worker端点。
3. Wrangler Configuration
3. Wrangler配置
File:
wrangler.jsoncjsonc
{
"name": "thesys-chat-worker",
"compatibility_date": "2025-10-26",
"main": "backend/src/index.ts",
"vars": {
"ENVIRONMENT": "production"
},
"assets": {
"directory": "dist",
"binding": "ASSETS"
}
}Add as a secret:
THESYS_API_KEYbash
npx wrangler secret put THESYS_API_KEY文件:
wrangler.jsoncjsonc
{
"name": "thesys-chat-worker",
"compatibility_date": "2025-10-26",
"main": "backend/src/index.ts",
"vars": {
"ENVIRONMENT": "production"
},
"assets": {
"directory": "dist",
"binding": "ASSETS"
}
}添加作为密钥:
THESYS_API_KEYbash
npx wrangler secret put THESYS_API_KEYCore Components
核心组件
<C1Chat>
- Pre-built Chat Component
<C1Chat><C1Chat>
- 预构建聊天组件
<C1Chat>When to use: Building conversational interfaces with minimal setup.
The component is a fully-featured chat UI with built-in:
C1Chat- Message history
- Streaming responses
- Thread management
- Loading states
- Error handling
- Responsive design
适用场景:以最少的配置构建对话式界面。
C1Chat- 消息历史
- 流式响应
- 线程管理
- 加载状态
- 错误处理
- 响应式设计
Basic Usage
基础用法
typescript
import { C1Chat } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
export default function App() {
return (
<C1Chat
apiUrl="/api/chat"
agentName="My AI Assistant"
logoUrl="https://example.com/logo.png"
/>
);
}typescript
import { C1Chat } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
export default function App() {
return (
<C1Chat
apiUrl="/api/chat"
agentName="My AI Assistant"
logoUrl="https://example.com/logo.png"
/>
);
}Key Props
关键属性
- (required) - Backend endpoint for chat completions
apiUrl - - Display name for the AI agent
agentName - - Logo/avatar for the agent
logoUrl - - Custom theme object (see Theming section)
theme - - For multi-thread support (advanced)
threadManager - - For thread list UI (advanced)
threadListManager - - Custom components (footer, thinking states)
customizeC1
- (必填)- 聊天补全的后端端点
apiUrl - - AI助手的显示名称
agentName - - 助手的Logo/头像
logoUrl - - 自定义主题对象(见主题部分)
theme - - 用于多线程支持(进阶)
threadManager - - 用于线程列表UI(进阶)
threadListManager - - 自定义组件(页脚、思考状态)
customizeC1
With Theme
带主题的用法
typescript
import { C1Chat } from "@thesysai/genui-sdk";
import { themePresets } from "@crayonai/react-ui";
<C1Chat
apiUrl="/api/chat"
theme={themePresets.candy} // or 'default', or custom object
/>typescript
import { C1Chat } from "@thesysai/genui-sdk";
import { themePresets } from "@crayonai/react-ui";
<C1Chat
apiUrl="/api/chat"
theme={themePresets.candy} // 或'default',或自定义对象
/><C1Component>
- Custom Integration Component
<C1Component><C1Component>
- 自定义集成组件
<C1Component>When to use: Need full control over state management and UI layout.
The is the low-level renderer. You handle:
C1Component- Fetching data
- Managing state
- Layout structure
- Error boundaries
适用场景:需要完全控制状态管理和UI布局。
C1Component- 数据获取
- 状态管理
- 布局结构
- 错误边界
Basic Usage
基础用法
typescript
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
const [c1Response, setC1Response] = useState("");
const [isStreaming, setIsStreaming] = useState(false);
// ... fetch logic
return (
<ThemeProvider>
<C1Component
c1Response={c1Response}
isStreaming={isStreaming}
updateMessage={(message) => setC1Response(message)}
onAction={({ llmFriendlyMessage }) => {
// Handle interactive actions (button clicks, form submissions)
console.log("User action:", llmFriendlyMessage);
// Make new API call with llmFriendlyMessage
}}
/>
</ThemeProvider>
);typescript
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
const [c1Response, setC1Response] = useState("");
const [isStreaming, setIsStreaming] = useState(false);
// ... 获取逻辑
return (
<ThemeProvider>
<C1Component
c1Response={c1Response}
isStreaming={isStreaming}
updateMessage={(message) => setC1Response(message)}
onAction={({ llmFriendlyMessage }) => {
// 处理与生成UI的用户交互(按钮点击、表单提交)
console.log("User action:", llmFriendlyMessage);
// 发送llmFriendlyMessage进行新的API调用
}}
/>
</ThemeProvider>
);Key Props
关键属性
- (required) - The C1 API response string
c1Response - - Whether response is still streaming (shows loading indicator)
isStreaming - - Callback for response updates during streaming
updateMessage - - Callback for user interactions with generated UI
onAction- : Pre-formatted message to send back to LLM
llmFriendlyMessage - : Raw action data from the component
rawAction
- (必填)- C1 API响应字符串
c1Response - - 响应是否仍在流式传输(显示加载指示器)
isStreaming - - 流式传输期间响应更新的回调
updateMessage - - 用户与生成UI交互的回调
onAction- :预格式化的消息,可发送回LLM
llmFriendlyMessage - :来自组件的原始操作数据
rawAction
Important: Must Wrap with ThemeProvider
重要提示:必须用ThemeProvider包裹
typescript
// ❌ Wrong - theme won't apply
<C1Component c1Response={response} />
// ✅ Correct
<ThemeProvider>
<C1Component c1Response={response} />
</ThemeProvider>typescript
// ❌ 错误 - 主题不会生效
<C1Component c1Response={response} />
// ✅ 正确
<ThemeProvider>
<C1Component c1Response={response} />
</ThemeProvider><ThemeProvider>
- Theming and Customization
<ThemeProvider><ThemeProvider>
- 主题与自定义
<ThemeProvider>When to use: Always wrap or customize appearance.
<C1Component><C1Chat>适用场景:始终包裹或自定义外观。
<C1Component><C1Chat>Theme Presets
主题预设
TheSys includes pre-built themes:
typescript
import { themePresets } from "@crayonai/react-ui";
// Available presets:
// - themePresets.default
// - themePresets.candy
// ... (check docs for full list)
<C1Chat theme={themePresets.candy} />TheSys包含预构建主题:
typescript
import { themePresets } from "@crayonai/react-ui";
// 可用预设:
// - themePresets.default
// - themePresets.candy
// ...(查看文档获取完整列表)
<C1Chat theme={themePresets.candy} />Dark Mode Support
深色模式支持
typescript
import { useSystemTheme } from "./hooks/useSystemTheme"; // custom hook
export default function App() {
const systemTheme = useSystemTheme(); // 'light' | 'dark'
return (
<C1Chat
apiUrl="/api/chat"
theme={{ ...themePresets.default, mode: systemTheme }}
/>
);
}typescript
import { useSystemTheme } from "./hooks/useSystemTheme"; // 自定义钩子
export default function App() {
const systemTheme = useSystemTheme(); // 'light' | 'dark'
return (
<C1Chat
apiUrl="/api/chat"
theme={{ ...themePresets.default, mode: systemTheme }}
/>
);
}Custom Theme Object
自定义主题对象
typescript
const customTheme = {
mode: "dark", // 'light' | 'dark' | 'system'
colors: {
primary: "#3b82f6",
secondary: "#8b5cf6",
background: "#1f2937",
foreground: "#f9fafb",
// ... more colors
},
fonts: {
body: "Inter, sans-serif",
heading: "Poppins, sans-serif",
},
borderRadius: "12px",
spacing: {
base: "16px",
},
};
<C1Chat theme={customTheme} />typescript
const customTheme = {
mode: "dark", // 'light' | 'dark' | 'system'
colors: {
primary: "#3b82f6",
secondary: "#8b5cf6",
background: "#1f2937",
foreground: "#f9fafb",
// ... 更多颜色
},
fonts: {
body: "Inter, sans-serif",
heading: "Poppins, sans-serif",
},
borderRadius: "12px",
spacing: {
base: "16px",
},
};
<C1Chat theme={customTheme} />CSS Overrides
CSS覆盖
Create a file:
custom.csscss
/* Override specific component styles */
.c1-chat-container {
max-width: 900px;
margin: 0 auto;
}
.c1-message-user {
background-color: #3b82f6 !important;
}
.c1-message-assistant {
background-color: #6b7280 !important;
}Then import:
typescript
import "@crayonai/react-ui/styles/index.css";
import "./custom.css"; // AFTER the default styles创建文件:
custom.csscss
/* 覆盖特定组件样式 */
.c1-chat-container {
max-width: 900px;
margin: 0 auto;
}
.c1-message-user {
background-color: #3b82f6 !important;
}
.c1-message-assistant {
background-color: #6b7280 !important;
}然后导入:
typescript
import "@crayonai/react-ui/styles/index.css";
import "./custom.css"; // 在默认样式之后导入AI Provider Integration
AI提供商集成
TheSys C1 API is OpenAI-compatible, meaning it works with any LLM provider that uses OpenAI's API format.
TheSys C1 API兼容OpenAI,意味着它可与任何采用OpenAI API格式的LLM提供商配合使用。
OpenAI Integration
OpenAI集成
Setup
配置
bash
npm install openaitypescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY, // TheSys API key
});bash
npm install openaitypescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY, // TheSys API密钥
});Model Selection
模型选择
TheSys supports OpenAI models through C1:
typescript
// GPT 5 (Stable - Recommended for Production)
model: "c1/openai/gpt-5/v-20250930"
// GPT 4.1 (Experimental)
model: "c1-exp/openai/gpt-4.1/v-20250617"TheSys通过C1支持OpenAI模型:
typescript
// GPT 5(稳定版 - 生产环境推荐)
model: "c1/openai/gpt-5/v-20250930"
// GPT 4.1(实验版)
model: "c1-exp/openai/gpt-4.1/v-20250617"Complete Example
完整示例
typescript
const response = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{
role: "system",
content: "You are a helpful assistant that generates interactive UI components.",
},
{
role: "user",
content: "Show me a comparison table of the top 3 project management tools.",
},
],
stream: true, // Enable streaming
temperature: 0.7,
max_tokens: 2000,
});typescript
const response = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{
role: "system",
content: "You are a helpful assistant that generates interactive UI components.",
},
{
role: "user",
content: "Show me a comparison table of the top 3 project management tools.",
},
],
stream: true, // 启用流式传输
temperature: 0.7,
max_tokens: 2000,
});Anthropic (Claude) Integration
Anthropic(Claude)集成
Setup
配置
TheSys C1 supports Anthropic's Claude models via OpenAI-compatible endpoint:
typescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});TheSys C1通过兼容OpenAI的端点支持Anthropic的Claude模型:
typescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});Model Selection
模型选择
typescript
// Claude Sonnet 4 (Stable - Recommended for Production)
model: "c1/anthropic/claude-sonnet-4/v-20250930"
// Claude 3.5 Haiku (Experimental)
model: "c1-exp/anthropic/claude-3.5-haiku/v-20250709"⚠️ Deprecated Models: Claude 3.5 Sonnet and Claude 3.7 Sonnet are no longer recommended. Use the stable Claude Sonnet 4 version above.
typescript
// Claude Sonnet 4(稳定版 - 生产环境推荐)
model: "c1/anthropic/claude-sonnet-4/v-20250930"
// Claude 3.5 Haiku(实验版)
model: "c1-exp/anthropic/claude-3.5-haiku/v-20250709"⚠️ 已弃用模型:Claude 3.5 Sonnet和Claude 3.7 Sonnet不再推荐使用。请使用上述稳定版Claude Sonnet 4。
Example with Claude
Claude示例
typescript
const response = await client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20250930",
messages: [
{
role: "system",
content: "You are Claude, an AI assistant that creates interactive interfaces.",
},
{
role: "user",
content: "Create a product comparison chart for electric vehicles.",
},
],
stream: true,
temperature: 0.8,
max_tokens: 4096,
});typescript
const response = await client.chat.completions.create({
model: "c1/anthropic/claude-sonnet-4/v-20250930",
messages: [
{
role: "system",
content: "You are Claude, an AI assistant that creates interactive interfaces.",
},
{
role: "user",
content: "Create a product comparison chart for electric vehicles.",
},
],
stream: true,
temperature: 0.8,
max_tokens: 4096,
});Model Specifications & Pricing
模型规格与定价
The table below shows the current stable and experimental models available via TheSys C1 API:
| Model | Model ID | Input Price | Output Price | Context | Max Output |
|---|---|---|---|---|---|
| Claude Sonnet 4 | | $6.00/M | $18.00/M | 180K | 64K |
| GPT 5 | | $2.50/M | $12.50/M | 380K | 128K |
| GPT 4.1 (exp) | | $4.00/M | $10.00/M | 1M | 32K |
| Claude 3.5 Haiku (exp) | | $1.60/M | $5.00/M | 180K | 8K |
Pricing Notes:
- Costs are per million tokens (M)
- Pricing is based on model name, regardless of endpoint type (embed or visualize)
- Stable models (prefixed with ) are recommended for production
c1/ - Experimental models (prefixed with ) are for testing and may have different behavior
c1-exp/
Model Versions: Model identifiers include version dates (e.g.,). Always check the TheSys Playground for the latest stable versions.v-20250930
下表显示了TheSys C1 API当前可用的稳定版和实验版模型:
| 模型 | 模型ID | 输入价格 | 输出价格 | 上下文长度 | 最大输出长度 |
|---|---|---|---|---|---|
| Claude Sonnet 4 | | $6.00/M | $18.00/M | 180K | 64K |
| GPT 5 | | $2.50/M | $12.50/M | 380K | 128K |
| GPT 4.1(实验版) | | $4.00/M | $10.00/M | 1M | 32K |
| Claude 3.5 Haiku(实验版) | | $1.60/M | $5.00/M | 180K | 8K |
定价说明:
- 成本基于每百万令牌(M)计算
- 定价基于模型名称,与端点类型(embed或visualize)无关
- 稳定版模型(前缀为)推荐用于生产环境
c1/ - 实验版模型(前缀为)用于测试,行为可能不同
c1-exp/
模型版本:模型标识符包含版本日期(例如)。请始终查看TheSys Playground获取最新稳定版本。v-20250930
Cloudflare Workers AI Integration
Cloudflare Workers AI集成
Setup with Workers AI Binding
与Workers AI绑定配置
typescript
// In your Cloudflare Worker
export default {
async fetch(request: Request, env: Env) {
// Use Workers AI directly (cheaper for some use cases)
const aiResponse = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Hello!" },
],
});
// Then transform to C1 format and send to frontend
// ...
}
};typescript
// 在您的Cloudflare Worker中
export default {
async fetch(request: Request, env: Env) {
// 直接使用Workers AI(某些场景下成本更低)
const aiResponse = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Hello!" },
],
});
// 然后转换为C1格式并发送到前端
// ...
}
};Hybrid Approach: Workers AI + C1
混合方式:Workers AI + C1
typescript
// Option 1: Use Workers AI for processing, C1 for UI generation
const thinkingResponse = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
messages: [{ role: "user", content: "Analyze this data..." }],
});
// Then use C1 to generate UI from the analysis
const c1Response = await fetch("https://api.thesys.dev/v1/embed/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${env.THESYS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{
role: "system",
content: "Generate a chart visualization for this data.",
},
{
role: "user",
content: thinkingResponse.response,
},
],
}),
});typescript
// 选项1:使用Workers AI处理,C1生成UI
const thinkingResponse = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
messages: [{ role: "user", content: "Analyze this data..." }],
});
// 然后使用C1根据分析结果生成UI
const c1Response = await fetch("https://api.thesys.dev/v1/embed/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${env.THESYS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "c1/openai/gpt-5/v-20250930",
messages: [
{
role: "system",
content: "Generate a chart visualization for this data.",
},
{
role: "user",
content: thinkingResponse.response,
},
],
}),
});Python Backend Integration
Python后端集成
TheSys provides a Python SDK for backend implementations with FastAPI, Flask, or Django.
TheSys为FastAPI、Flask或Django的后端实现提供Python SDK。
Setup
配置
bash
pip install thesys-genui-sdk openaibash
pip install thesys-genui-sdk openaiFastAPI Example
FastAPI示例
python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from thesys_genui_sdk import with_c1_response, write_content
import openai
import os
app = FastAPI()
client = openai.OpenAI(
base_url="https://api.thesys.dev/v1/embed",
api_key=os.getenv("THESYS_API_KEY")
)
@app.post("/api/chat")
@with_c1_response # Automatically handles streaming headers
async def chat_endpoint(request: dict):
prompt = request.get("prompt")
stream = client.chat.completions.create(
model="c1/anthropic/claude-sonnet-4/v-20250930",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
stream=True
)
# Stream chunks to frontend
async def generate():
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
yield write_content(content)
return StreamingResponse(generate(), media_type="text/event-stream")python
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from thesys_genui_sdk import with_c1_response, write_content
import openai
import os
app = FastAPI()
client = openai.OpenAI(
base_url="https://api.thesys.dev/v1/embed",
api_key=os.getenv("THESYS_API_KEY")
)
@app.post("/api/chat")
@with_c1_response # 自动处理流式传输请求头
async def chat_endpoint(request: dict):
prompt = request.get("prompt")
stream = client.chat.completions.create(
model="c1/anthropic/claude-sonnet-4/v-20250930",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
stream=True
)
// 向前端流式传输数据块
async def generate():
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
yield write_content(content)
return StreamingResponse(generate(), media_type="text/event-stream")Key Features
核心特性
- decorator: Automatically sets proper response headers for streaming
@with_c1_response - helper: Formats chunks for C1Component rendering
write_content - Framework agnostic: Works with FastAPI, Flask, Django, or any Python web framework
- 装饰器:自动设置流式传输所需的响应头
@with_c1_response - 辅助函数:格式化数据块以适配C1Component渲染
write_content - 框架无关:适用于FastAPI、Flask、Django或任何Python Web框架
Flask Example
Flask示例
python
from flask import Flask, request, Response
from thesys_genui_sdk import with_c1_response, write_content
import openai
import os
app = Flask(__name__)
client = openai.OpenAI(
base_url="https://api.thesys.dev/v1/embed",
api_key=os.getenv("THESYS_API_KEY")
)
@app.route("/api/chat", methods=["POST"])
@with_c1_response
def chat():
data = request.get_json()
prompt = data.get("prompt")
stream = client.chat.completions.create(
model="c1/openai/gpt-5/v-20250930",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
stream=True
)
def generate():
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
yield write_content(content)
return Response(generate(), mimetype="text/event-stream")python
from flask import Flask, request, Response
from thesys_genui_sdk import with_c1_response, write_content
import openai
import os
app = Flask(__name__)
client = openai.OpenAI(
base_url="https://api.thesys.dev/v1/embed",
api_key=os.getenv("THESYS_API_KEY")
)
@app.route("/api/chat", methods=["POST"])
@with_c1_response
def chat():
data = request.get_json()
prompt = data.get("prompt")
stream = client.chat.completions.create(
model="c1/openai/gpt-5/v-20250930",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
stream=True
)
def generate():
for chunk in stream:
content = chunk.choices[0].delta.content
if content:
yield write_content(content)
return Response(generate(), mimetype="text/event-stream")Universal Patterns (Any Provider)
通用模式(任何提供商)
Error Handling
错误处理
typescript
try {
const response = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [...],
stream: true,
});
// Process stream...
} catch (error) {
if (error.status === 429) {
// Rate limit - implement exponential backoff
await new Promise(resolve => setTimeout(resolve, 1000));
// Retry...
} else if (error.status === 401) {
// Invalid API key
console.error("Authentication failed. Check THESYS_API_KEY");
} else {
// Other errors
console.error("API Error:", error);
}
}typescript
try {
const response = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [...],
stream: true,
});
// 处理流...
} catch (error) {
if (error.status === 429) {
// 速率限制 - 实现指数退避
await new Promise(resolve => setTimeout(resolve, 1000));
// 重试...
} else if (error.status === 401) {
// 无效API密钥
console.error("Authentication failed. Check THESYS_API_KEY");
} else {
// 其他错误
console.error("API Error:", error);
}
}Streaming with transformStream
使用transformStream进行流式传输
typescript
import { transformStream } from "@crayonai/stream";
const llmStream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [...],
stream: true,
});
// Transform OpenAI stream to C1 stream
const c1Stream = transformStream(llmStream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
}) as ReadableStream<string>;
return new Response(c1Stream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});typescript
import { transformStream } from "@crayonai/stream";
const llmStream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [...],
stream: true,
});
// 将OpenAI流转换为C1流
const c1Stream = transformStream(llmStream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
}) as ReadableStream<string>;
return new Response(c1Stream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});Tool Calling with Zod Schemas
使用Zod Schema进行工具调用
Tool calling allows your AI to invoke functions and display interactive UI for data collection, external API calls, and complex workflows.
工具调用允许您的AI调用函数,并展示用于数据收集、外部API调用和复杂工作流的交互式UI。
1. Define Tools with Zod
1. 使用Zod定义工具
typescript
import { z } from "zod";
import zodToJsonSchema from "zod-to-json-schema";
// Define the tool schema
const webSearchSchema = z.object({
query: z.string().describe("The search query"),
max_results: z.number().int().min(1).max(10).default(5)
.describe("Maximum number of results to return"),
});
// Convert to OpenAI tool format
export const webSearchTool = {
type: "function" as const,
function: {
name: "web_search",
description: "Search the web for current information",
parameters: zodToJsonSchema(webSearchSchema),
},
};typescript
import { z } from "zod";
import zodToJsonSchema from "zod-to-json-schema";
// 定义工具schema
const webSearchSchema = z.object({
query: z.string().describe("The search query"),
max_results: z.number().int().min(1).max(10).default(5)
.describe("Maximum number of results to return"),
});
// 转换为OpenAI工具格式
export const webSearchTool = {
type: "function" as const,
function: {
name: "web_search",
description: "Search the web for current information",
parameters: zodToJsonSchema(webSearchSchema),
},
};2. More Complex Example: Order Management
2. 更复杂的示例:订单管理
typescript
import { z } from "zod";
// Discriminated union for different product types
const productOrderSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal("gloves"),
size: z.enum(["S", "M", "L", "XL"]),
color: z.string(),
quantity: z.number().int().min(1),
}),
z.object({
type: z.literal("hat"),
style: z.enum(["beanie", "baseball", "fedora"]),
color: z.string(),
quantity: z.number().int().min(1),
}),
z.object({
type: z.literal("scarf"),
length: z.enum(["short", "medium", "long"]),
material: z.enum(["wool", "cotton", "silk"]),
quantity: z.number().int().min(1),
}),
]);
const createOrderSchema = z.object({
customer_email: z.string().email(),
items: z.array(productOrderSchema).min(1),
shipping_address: z.object({
street: z.string(),
city: z.string(),
state: z.string(),
zip: z.string(),
}),
});
export const createOrderTool = {
type: "function" as const,
function: {
name: "create_order",
description: "Create a new order for products",
parameters: zodToJsonSchema(createOrderSchema),
},
};typescript
import { z } from "zod";
// 不同产品类型的判别联合
const productOrderSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal("gloves"),
size: z.enum(["S", "M", "L", "XL"]),
color: z.string(),
quantity: z.number().int().min(1),
}),
z.object({
type: z.literal("hat"),
style: z.enum(["beanie", "baseball", "fedora"]),
color: z.string(),
quantity: z.number().int().min(1),
}),
z.object({
type: z.literal("scarf"),
length: z.enum(["short", "medium", "long"]),
material: z.enum(["wool", "cotton", "silk"]),
quantity: z.number().int().min(1),
}),
]);
const createOrderSchema = z.object({
customer_email: z.string().email(),
items: z.array(productOrderSchema).min(1),
shipping_address: z.object({
street: z.string(),
city: z.string(),
state: z.string(),
zip: z.string(),
}),
});
export const createOrderTool = {
type: "function" as const,
function: {
name: "create_order",
description: "Create a new order for products",
parameters: zodToJsonSchema(createOrderSchema),
},
};3. Implement Tool Execution
3. 实现工具执行
typescript
// tools.ts
import { TavilySearchAPIClient } from "@tavily/core";
const tavily = new TavilySearchAPIClient({
apiKey: process.env.TAVILY_API_KEY,
});
export async function executeWebSearch(query: string, max_results: number) {
const results = await tavily.search(query, {
maxResults: max_results,
includeAnswer: true,
});
return {
query,
results: results.results.map((r) => ({
title: r.title,
url: r.url,
snippet: r.content,
})),
answer: results.answer,
};
}
export async function executeCreateOrder(orderData: z.infer<typeof createOrderSchema>) {
// Validate with Zod
const validated = createOrderSchema.parse(orderData);
// Save to database
const orderId = await saveOrderToDatabase(validated);
return {
success: true,
orderId,
message: `Order ${orderId} created successfully`,
};
}typescript
// tools.ts
import { TavilySearchAPIClient } from "@tavily/core";
const tavily = new TavilySearchAPIClient({
apiKey: process.env.TAVILY_API_KEY,
});
export async function executeWebSearch(query: string, max_results: number) {
const results = await tavily.search(query, {
maxResults: max_results,
includeAnswer: true,
});
return {
query,
results: results.results.map((r) => ({
title: r.title,
url: r.url,
snippet: r.content,
})),
answer: results.answer,
};
}
export async function executeCreateOrder(orderData: z.infer<typeof createOrderSchema>) {
// 使用Zod验证
const validated = createOrderSchema.parse(orderData);
// 保存到数据库
const orderId = await saveOrderToDatabase(validated);
return {
success: true,
orderId,
message: `Order ${orderId} created successfully`,
};
}4. Integrate Tools in API Route
4. 在API路由中集成工具
typescript
import { NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
import { webSearchTool, createOrderTool } from "./tools";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
export async function POST(req: NextRequest) {
const { prompt } = await req.json();
const llmStream = await client.beta.chat.completions.runTools({
model: "c1/anthropic/claude-sonnet-4/v-20250930",
messages: [
{
role: "system",
content: "You are a helpful shopping assistant. Use tools to search for products and create orders.",
},
{
role: "user",
content: prompt,
},
],
stream: true,
tools: [webSearchTool, createOrderTool],
toolChoice: "auto", // Let AI decide when to use tools
});
// Handle tool execution
llmStream.on("message", async (event) => {
if (event.tool_calls) {
for (const toolCall of event.tool_calls) {
if (toolCall.function.name === "web_search") {
const args = JSON.parse(toolCall.function.arguments);
const result = await executeWebSearch(args.query, args.max_results);
// Send result back to LLM...
} else if (toolCall.function.name === "create_order") {
const args = JSON.parse(toolCall.function.arguments);
const result = await executeCreateOrder(args);
// Send result back to LLM...
}
}
}
});
const responseStream = transformStream(llmStream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
}) as ReadableStream<string>;
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
}typescript
import { NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";
import { transformStream } from "@crayonai/stream";
import { webSearchTool, createOrderTool } from "./tools";
const client = new OpenAI({
baseURL: "https://api.thesys.dev/v1/embed",
apiKey: process.env.THESYS_API_KEY,
});
export async function POST(req: NextRequest) {
const { prompt } = await req.json();
const llmStream = await client.beta.chat.completions.runTools({
model: "c1/anthropic/claude-sonnet-4/v-20250930",
messages: [
{
role: "system",
content: "You are a helpful shopping assistant. Use tools to search for products and create orders.",
},
{
role: "user",
content: prompt,
},
],
stream: true,
tools: [webSearchTool, createOrderTool],
toolChoice: "auto", // 让AI决定何时使用工具
});
// 处理工具执行
llmStream.on("message", async (event) => {
if (event.tool_calls) {
for (const toolCall of event.tool_calls) {
if (toolCall.function.name === "web_search") {
const args = JSON.parse(toolCall.function.arguments);
const result = await executeWebSearch(args.query, args.max_results);
// 将结果发送回LLM...
} else if (toolCall.function.name === "create_order") {
const args = JSON.parse(toolCall.function.arguments);
const result = await executeCreateOrder(args);
// 将结果发送回LLM...
}
}
}
});
const responseStream = transformStream(llmStream, (chunk) => {
return chunk.choices[0]?.delta?.content || "";
}) as ReadableStream<string>;
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
}5. Display Tool Results in UI
5. 在UI中展示工具结果
The C1Component automatically renders tool interactions as forms and displays results. You just need to handle the callback:
onActiontypescript
<C1Component
c1Response={c1Response}
onAction={async ({ llmFriendlyMessage, rawAction }) => {
console.log("Tool action triggered:", rawAction);
// Make API call with llmFriendlyMessage to continue conversation
await makeApiCall(llmFriendlyMessage);
}}
/>C1Component会自动将工具交互渲染为表单并展示结果。您只需处理回调:
onActiontypescript
<C1Component
c1Response={c1Response}
onAction={async ({ llmFriendlyMessage, rawAction }) => {
console.log("Tool action triggered:", rawAction);
// 发送llmFriendlyMessage进行API调用以继续对话
await makeApiCall(llmFriendlyMessage);
}}
/>Advanced Features
进阶特性
Thread Management (Multi-Conversation Support)
线程管理(多对话支持)
Enable users to have multiple conversation threads with thread switching, history, and persistence.
允许用户进行多对话线程,支持线程切换、历史记录和持久化。
1. Define Thread API
1. 定义线程API
Create backend endpoints:
- - List all threads
GET /api/threads - - Create new thread
POST /api/threads - - Update thread title
PUT /api/threads/:id - - Delete thread
DELETE /api/threads/:id - - Load thread messages
GET /api/threads/:id/messages
创建后端端点:
- - 列出所有线程
GET /api/threads - - 创建新线程
POST /api/threads - - 更新线程标题
PUT /api/threads/:id - - 删除线程
DELETE /api/threads/:id - - 加载线程消息
GET /api/threads/:id/messages
2. Implement Thread Managers
2. 实现线程管理器
typescript
import {
useThreadListManager,
useThreadManager,
} from "@thesysai/genui-sdk";
import { Thread, Message, UserMessage } from "@crayonai/react-core";
export default function App() {
const threadListManager = useThreadListManager({
// Fetch all threads
fetchThreadList: async (): Promise<Thread[]> => {
const response = await fetch("/api/threads");
return response.json();
},
// Delete thread
deleteThread: async (threadId: string): Promise<void> => {
await fetch(`/api/threads/${threadId}`, { method: "DELETE" });
},
// Update thread title
updateThread: async (thread: Thread): Promise<Thread> => {
const response = await fetch(`/api/threads/${thread.threadId}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: thread.title }),
});
return response.json();
},
// Create new thread
createThread: async (firstMessage: UserMessage): Promise<Thread> => {
const response = await fetch("/api/threads", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: firstMessage.message || "New Chat",
}),
});
return response.json();
},
// URL synchronization
onSwitchToNew: () => {
window.history.replaceState(null, "", window.location.pathname);
},
onSelectThread: (threadId: string) => {
const url = new URL(window.location.href);
url.searchParams.set("threadId", threadId);
window.history.replaceState(null, "", url.toString());
},
});
const threadManager = useThreadManager({
threadListManager,
// Load messages for selected thread
loadThread: async (threadId: string): Promise<Message[]> => {
const response = await fetch(`/api/threads/${threadId}/messages`);
return response.json();
},
// Handle message updates (e.g., feedback)
onUpdateMessage: async ({ message }: { message: Message }) => {
if (threadListManager.selectedThreadId) {
await fetch(
`/api/threads/${threadListManager.selectedThreadId}/message`,
{
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(message),
}
);
}
},
});
return (
<C1Chat
threadManager={threadManager}
threadListManager={threadListManager}
/>
);
}typescript
import {
useThreadListManager,
useThreadManager,
} from "@thesysai/genui-sdk";
import { Thread, Message, UserMessage } from "@crayonai/react-core";
export default function App() {
const threadListManager = useThreadListManager({
// 获取所有线程
fetchThreadList: async (): Promise<Thread[]> => {
const response = await fetch("/api/threads");
return response.json();
},
// 删除线程
deleteThread: async (threadId: string): Promise<void> => {
await fetch(`/api/threads/${threadId}`, { method: "DELETE" });
},
// 更新线程标题
updateThread: async (thread: Thread): Promise<Thread> => {
const response = await fetch(`/api/threads/${thread.threadId}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: thread.title }),
});
return response.json();
},
// 创建新线程
createThread: async (firstMessage: UserMessage): Promise<Thread> => {
const response = await fetch("/api/threads", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: firstMessage.message || "New Chat",
}),
});
return response.json();
},
// URL同步
onSwitchToNew: () => {
window.history.replaceState(null, "", window.location.pathname);
},
onSelectThread: (threadId: string) => {
const url = new URL(window.location.href);
url.searchParams.set("threadId", threadId);
window.history.replaceState(null, "", url.toString());
},
});
const threadManager = useThreadManager({
threadListManager,
// 加载选中线程的消息
loadThread: async (threadId: string): Promise<Message[]> => {
const response = await fetch(`/api/threads/${threadId}/messages`);
return response.json();
},
// 处理消息更新(例如反馈)
onUpdateMessage: async ({ message }: { message: Message }) => {
if (threadListManager.selectedThreadId) {
await fetch(
`/api/threads/${threadListManager.selectedThreadId}/message`,
{
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(message),
}
);
}
},
});
return (
<C1Chat
threadManager={threadManager}
threadListManager={threadListManager}
/>
);
}Thinking States (Progress Indicators)
思考状态(进度指示器)
Show users what the AI is doing during processing (searching web, analyzing data, etc.).
在处理过程中向用户展示AI正在执行的操作(搜索网页、分析数据等)。
1. Server-Side: Write Think Items
1. 服务端:写入思考项
typescript
import { makeC1Response } from "@thesysai/genui-sdk/server";
export async function POST(req: NextRequest) {
const c1Response = makeC1Response();
// Initial thinking state
c1Response.writeThinkItem({
title: "Thinking…",
description: "Analyzing your question and planning the response.",
});
const { prompt } = await req.json();
// Update thinking state when calling tools
const llmStream = await client.beta.chat.completions.runTools({
model: "c1/anthropic/claude-sonnet-4/v-20250930",
messages: [...],
tools: [
getWebSearchTool(() => {
c1Response.writeThinkItem({
title: "Searching the web…",
description: "Finding the most relevant and up-to-date information.",
});
}),
],
});
transformStream(
llmStream,
(chunk) => {
const content = chunk.choices[0]?.delta?.content;
if (content) {
c1Response.writeContent(content);
}
return content;
},
{
onEnd: () => {
c1Response.end();
},
}
);
return new NextResponse(c1Response.responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
}typescript
import { makeC1Response } from "@thesysai/genui-sdk/server";
export async function POST(req: NextRequest) {
const c1Response = makeC1Response();
// 初始思考状态
c1Response.writeThinkItem({
title: "Thinking…",
description: "Analyzing your question and planning the response.",
});
const { prompt } = await req.json();
// 调用工具时更新思考状态
const llmStream = await client.beta.chat.completions.runTools({
model: "c1/anthropic/claude-sonnet-4/v-20250930",
messages: [...],
tools: [
getWebSearchTool(() => {
c1Response.writeThinkItem({
title: "Searching the web…",
description: "Finding the most relevant and up-to-date information.",
});
}),
],
});
transformStream(
llmStream,
(chunk) => {
const content = chunk.choices[0]?.delta?.content;
if (content) {
c1Response.writeContent(content);
}
return content;
},
{
onEnd: () => {
c1Response.end();
},
}
);
return new NextResponse(c1Response.responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
}2. Custom Think Component
2. 自定义思考组件
typescript
// CustomThink.tsx
import { ThinkItem } from "@crayonai/react-core";
export function CustomThink({ item }: { item: ThinkItem }) {
return (
<div className="custom-think">
<div className="spinner" />
<div>
<h4>{item.title}</h4>
<p>{item.description}</p>
</div>
</div>
);
}
// In your app
<C1Chat
apiUrl="/api/chat"
customizeC1={{ thinkComponent: CustomThink }}
/>typescript
// CustomThink.tsx
import { ThinkItem } from "@crayonai/react-core";
export function CustomThink({ item }: { item: ThinkItem }) {
return (
<div className="custom-think">
<div className="spinner" />
<div>
<h4>{item.title}</h4>
<p>{item.description}</p>
</div>
</div>
);
}
// 在您的应用中
<C1Chat
apiUrl="/api/chat"
customizeC1={{ thinkComponent: CustomThink }}
/>Message and Thread Sharing
消息与线程分享
Enable users to share conversations via public URLs.
允许用户通过公共URL分享对话。
1. Generate Share Links
1. 生成分享链接
typescript
import { C1ShareThread } from "@thesysai/genui-sdk";
const selectedThreadId = threadListManager.selectedThreadId;
<C1ShareThread
generateShareLink={
!selectedThreadId
? undefined
: async () => {
const baseUrl = window.location.origin;
return `${baseUrl}/shared/${selectedThreadId}`;
}
}
/>typescript
import { C1ShareThread } from "@thesysai/genui-sdk";
const selectedThreadId = threadListManager.selectedThreadId;
<C1ShareThread
generateShareLink={
!selectedThreadId
? undefined
: async () => {
const baseUrl = window.location.origin;
return `${baseUrl}/shared/${selectedThreadId}`;
}
}
/>2. Create Shared View Page
2. 创建共享视图页面
typescript
// app/shared/[threadId]/page.tsx
"use client";
import { C1ChatViewer } from "@thesysai/genui-sdk";
import { Message } from "@crayonai/react-core";
import { use, useEffect, useState } from "react";
import "@crayonai/react-ui/styles/index.css";
export default function ViewSharedThread({
params,
}: {
params: Promise<{ threadId: string }>;
}) {
const { threadId } = use(params);
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
const fetchMessages = async () => {
const response = await fetch(`/api/share/${threadId}`);
const data = await response.json();
setMessages(data);
};
fetchMessages();
}, [threadId]);
if (!messages.length) return <div>Loading...</div>;
return <C1ChatViewer messages={messages} />;
}typescript
// app/shared/[threadId]/page.tsx
"use client";
import { C1ChatViewer } from "@thesysai/genui-sdk";
import { Message } from "@crayonai/react-core";
import { use, useEffect, useState } from "react";
import "@crayonai/react-ui/styles/index.css";
export default function ViewSharedThread({
params,
}: {
params: Promise<{ threadId: string }>;
}) {
const { threadId } = use(params);
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
const fetchMessages = async () => {
const response = await fetch(`/api/share/${threadId}`);
const data = await response.json();
setMessages(data);
};
fetchMessages();
}, [threadId]);
if (!messages.length) return <div>Loading...</div>;
return <C1ChatViewer messages={messages} />;
}Production Patterns
生产环境模式
Message Persistence
消息持久化
Don't use in-memory storage in production!
typescript
// ❌ Bad - loses data on restart
const messageStore = new Map<string, Message[]>();
// ✅ Good - use a database
import { db } from "./database"; // D1, PostgreSQL, etc.
export async function saveMessage(threadId: string, message: Message) {
await db.insert(messages).values({
threadId,
role: message.role,
content: message.content,
createdAt: new Date(),
});
}
export async function getThreadMessages(threadId: string): Promise<Message[]> {
return db.select().from(messages).where(eq(messages.threadId, threadId));
}生产环境请勿使用内存存储!
typescript
// ❌ 错误 - 重启后数据丢失
const messageStore = new Map<string, Message[]>();
// ✅ 正确 - 使用数据库
import { db } from "./database"; // D1、PostgreSQL等
export async function saveMessage(threadId: string, message: Message) {
await db.insert(messages).values({
threadId,
role: message.role,
content: message.content,
createdAt: new Date(),
});
}
export async function getThreadMessages(threadId: string): Promise<Message[]> {
return db.select().from(messages).where(eq(messages.threadId, threadId));
}Authentication Integration (Clerk Example)
认证集成(Clerk示例)
typescript
import { auth } from "@clerk/nextjs";
export async function POST(req: NextRequest) {
const { userId } = auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Proceed with chat logic, scoping to user
const userThreads = await db
.select()
.from(threads)
.where(eq(threads.userId, userId));
// ...
}typescript
import { auth } from "@clerk/nextjs";
export async function POST(req: NextRequest) {
const { userId } = auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// 继续聊天逻辑,限定用户范围
const userThreads = await db
.select()
.from(threads)
.where(eq(threads.userId, userId));
// ...
}Rate Limiting
速率限制
typescript
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, "1 m"), // 10 requests per minute
});
export async function POST(req: NextRequest) {
const { userId } = auth();
const { success } = await ratelimit.limit(userId);
if (!success) {
return NextResponse.json(
{ error: "Rate limit exceeded. Please try again later." },
{ status: 429 }
);
}
// Proceed...
}typescript
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, "1 m"), // 每分钟10次请求
});
export async function POST(req: NextRequest) {
const { userId } = auth();
const { success } = await ratelimit.limit(userId);
if (!success) {
return NextResponse.json(
{ error: "Rate limit exceeded. Please try again later." },
{ status: 429 }
);
}
// 继续...
}Error Boundaries
错误边界
typescript
import { ErrorBoundary } from "react-error-boundary";
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<h2>Something went wrong</h2>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
);
}
export default function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<C1Chat apiUrl="/api/chat" />
</ErrorBoundary>
);
}typescript
import { ErrorBoundary } from "react-error-boundary";
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<h2>Something went wrong</h2>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
);
}
export default function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<C1Chat apiUrl="/api/chat" />
</ErrorBoundary>
);
}Performance Optimization
性能优化
typescript
// 1. Lazy load C1Chat
import { lazy, Suspense } from "react";
const C1Chat = lazy(() =>
import("@thesysai/genui-sdk").then((mod) => ({ default: mod.C1Chat }))
);
export default function App() {
return (
<Suspense fallback={<div>Loading chat...</div>}>
<C1Chat apiUrl="/api/chat" />
</Suspense>
);
}
// 2. Memoize expensive computations
import { useMemo } from "react";
const threadListManager = useMemo(
() =>
useThreadListManager({
// ... config
}),
[] // Empty deps - only create once
);typescript
// 1. 懒加载C1Chat
import { lazy, Suspense } from "react";
const C1Chat = lazy(() =>
import("@thesysai/genui-sdk").then((mod) => ({ default: mod.C1Chat }))
);
export default function App() {
return (
<Suspense fallback={<div>Loading chat...</div>}>
<C1Chat apiUrl="/api/chat" />
</Suspense>
);
}
// 2. 记忆化昂贵计算
import { useMemo } from "react";
const threadListManager = useMemo(
() =>
useThreadListManager({
// ... 配置
}),
[] // 空依赖 - 仅创建一次
);Common Errors & Solutions
常见错误与解决方案
1. Empty Agent Responses
1. Agent空响应
Problem: AI returns empty responses, UI shows nothing.
Cause: Incorrect streaming transformation or response format.
Solution:
typescript
// ✅ Use transformStream helper
import { transformStream } from "@crayonai/stream";
const c1Stream = transformStream(llmStream, (chunk) => {
return chunk.choices[0]?.delta?.content || ""; // Fallback to empty string
}) as ReadableStream<string>;问题:AI返回空响应,UI无内容展示。
原因:流式传输转换错误或响应格式不正确。
解决方案:
typescript
// ✅ 使用transformStream辅助函数
import { transformStream } from "@crayonai/stream";
const c1Stream = transformStream(llmStream, (chunk) => {
return chunk.choices[0]?.delta?.content || ""; // 回退到空字符串
}) as ReadableStream<string>;2. Model Not Following System Prompt
2. 模型不遵循系统提示
Problem: AI ignores instructions in system prompt.
Cause: System prompt is not first in messages array or improperly formatted.
Solution:
typescript
// ✅ System prompt MUST be first
const messages = [
{ role: "system", content: "You are a helpful assistant." }, // FIRST!
...conversationHistory,
{ role: "user", content: userPrompt },
];
// ❌ Wrong - system prompt after user messages
const messages = [
{ role: "user", content: "Hello" },
{ role: "system", content: "..." }, // TOO LATE
];问题:AI忽略系统提示中的指令。
原因:系统提示未放在消息数组首位或格式不正确。
解决方案:
typescript
// ✅ 系统提示必须是第一个
const messages = [
{ role: "system", content: "You are a helpful assistant." }, // 首位!
...conversationHistory,
{ role: "user", content: userPrompt },
];
// ❌ 错误 - 系统提示在用户消息之后
const messages = [
{ role: "user", content: "Hello" },
{ role: "system", content: "..." }, // 太晚了
];3. Version Compatibility Errors
3. 版本兼容性错误
Problem: or component rendering errors.
TypeError: Cannot read property 'X' of undefinedCause: Mismatched SDK versions.
Solution: Check compatibility matrix:
| C1 Version | @thesysai/genui-sdk | @crayonai/react-ui | @crayonai/react-core |
|---|---|---|---|
| v-20250930 | ~0.6.40 | ~0.8.42 | ~0.7.6 |
bash
undefined问题:或组件渲染错误。
TypeError: Cannot read property 'X' of undefined原因:SDK版本不匹配。
解决方案:查看兼容性矩阵:
| C1版本 | @thesysai/genui-sdk | @crayonai/react-ui | @crayonai/react-core |
|---|---|---|---|
| v-20250930 | ~0.6.40 | ~0.8.42 | ~0.7.6 |
bash
// 更新到兼容版本
npm install @thesysai/genui-sdk@0.6.40 @crayonai/react-ui@0.8.42 @crayonai/react-core@0.7.6Update to compatible versions
4. 主题不生效
npm install @thesysai/genui-sdk@0.6.40 @crayonai/react-ui@0.8.42 @crayonai/react-core@0.7.6
---问题:UI组件与自定义主题不匹配。
原因:缺少包裹。
ThemeProvider解决方案:
typescript
// ❌ 错误
<C1Component c1Response={response} />
// ✅ 正确
<ThemeProvider theme={customTheme}>
<C1Component c1Response={response} />
</ThemeProvider>4. Theme Not Applying
5. 流式传输不工作
Problem: UI components don't match custom theme.
Cause: Missing wrapper.
ThemeProviderSolution:
typescript
// ❌ Wrong
<C1Component c1Response={response} />
// ✅ Correct
<ThemeProvider theme={customTheme}>
<C1Component c1Response={response} />
</ThemeProvider>问题:UI不实时更新,等待完整响应后才展示。
原因:未启用流式传输或响应头设置不正确。
解决方案:
typescript
// 1. 在API调用中启用流式传输
const stream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [...],
stream: true, // ✅ 重要
});
// 2. 设置正确的响应头
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
// 3. 传递isStreaming属性
<C1Component
c1Response={response}
isStreaming={true} // ✅ 显示加载指示器
/>5. Streaming Not Working
6. 工具调用失败
Problem: UI doesn't update in real-time, waits for full response.
Cause: Not using streaming or improper response headers.
Solution:
typescript
// 1. Enable streaming in API call
const stream = await client.chat.completions.create({
model: "c1/openai/gpt-5/v-20250930",
messages: [...],
stream: true, // ✅ IMPORTANT
});
// 2. Set proper response headers
return new NextResponse(responseStream, {
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache, no-transform",
"Connection": "keep-alive",
},
});
// 3. Pass isStreaming prop
<C1Component
c1Response={response}
isStreaming={true} // ✅ Shows loading indicator
/>问题:工具未执行或验证错误。
原因:Zod schema无效或工具格式不正确。
解决方案:
typescript
import { z } from "zod";
import zodToJsonSchema from "zod-to-json-schema";
// ✅ 带描述的正确Zod schema
const toolSchema = z.object({
query: z.string().describe("Search query"), // 描述所有字段
limit: z.number().int().min(1).max(100).describe("Max results"),
});
// ✅ 转换为OpenAI格式
const tool = {
type: "function" as const,
function: {
name: "search_web",
description: "Search the web for information", // 清晰描述
parameters: zodToJsonSchema(toolSchema), // 转换schema
},
};
// ✅ 验证传入的工具调用
const args = toolSchema.parse(JSON.parse(toolCall.function.arguments));6. Tool Calling Failures
7. 线程状态不持久
Problem: Tools not executing or validation errors.
Cause: Invalid Zod schema or incorrect tool format.
Solution:
typescript
import { z } from "zod";
import zodToJsonSchema from "zod-to-json-schema";
// ✅ Proper Zod schema with descriptions
const toolSchema = z.object({
query: z.string().describe("Search query"), // DESCRIBE all fields
limit: z.number().int().min(1).max(100).describe("Max results"),
});
// ✅ Convert to OpenAI format
const tool = {
type: "function" as const,
function: {
name: "search_web",
description: "Search the web for information", // Clear description
parameters: zodToJsonSchema(toolSchema), // Convert schema
},
};
// ✅ Validate incoming tool calls
const args = toolSchema.parse(JSON.parse(toolCall.function.arguments));问题:页面刷新后线程消失。
原因:无后端持久化,使用内存存储。
解决方案:实现数据库存储(见生产环境模式部分)。
7. Thread State Not Persisting
8. CSS冲突
Problem: Threads disappear on page refresh.
Cause: No backend persistence, using in-memory storage.
Solution: Implement database storage (see Production Patterns section).
问题:C1组件样式与应用样式冲突。
原因:CSS导入顺序或全局样式覆盖。
解决方案:
typescript
// ✅ 正确导入顺序
import "@crayonai/react-ui/styles/index.css"; // 先导入C1样式
import "./your-app.css"; // 再导入您的样式
// 在您的CSS中,必要时使用特异性
.your-custom-class .c1-message {
/* 覆盖特定样式 */
}8. CSS Conflicts
9. TypeScript类型错误
Problem: Styles from C1 components clash with app styles.
Cause: CSS import order or global styles overriding.
Solution:
typescript
// ✅ Correct import order
import "@crayonai/react-ui/styles/index.css"; // C1 styles FIRST
import "./your-app.css"; // Your styles SECOND
// In your CSS, use specificity if needed
.your-custom-class .c1-message {
/* Override specific styles */
}问题:TypeScript提示缺少类型或类型不兼容。
原因:包版本过时或缺少类型定义。
解决方案:
bash
// 更新包
npm install @thesysai/genui-sdk@latest @crayonai/react-ui@latest @crayonai/react-core@latest
// 如果仍有错误,检查tsconfig.json
{
"compilerOptions": {
"moduleResolution": "bundler", // 或"node16"
"skipLibCheck": true // 跳过node_modules的类型检查
}
}9. TypeScript Type Errors
10. API的CORS错误
Problem: TypeScript complains about missing types or incompatible types.
Cause: Outdated package versions or missing type definitions.
Solution:
bash
undefined问题:调用后端时出现错误。
Access-Control-Allow-Origin原因:API响应缺少CORS头。
解决方案:
typescript
// Next.js API路由
export async function POST(req: NextRequest) {
const response = new NextResponse(stream, {
headers: {
"Content-Type": "text/event-stream",
"Access-Control-Allow-Origin": "*", // 或特定域名
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
},
});
return response;
}
// Express
app.use(cors({
origin: "http://localhost:5173", // 您的前端URL
methods: ["POST", "OPTIONS"],
}));Update packages
11. 速率限制问题
npm install @thesysai/genui-sdk@latest @crayonai/react-ui@latest @crayonai/react-core@latest
问题:API调用因429错误失败,无重试机制。
原因:无速率限制退避逻辑。
解决方案:
typescript
async function callApiWithRetry(apiCall, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await apiCall();
} catch (error) {
if (error.status === 429 && i < maxRetries - 1) {
const waitTime = Math.pow(2, i) * 1000; // 指数退避
await new Promise((resolve) => setTimeout(resolve, waitTime));
continue;
}
throw error;
}
}
}
// 使用
const response = await callApiWithRetry(() =>
client.chat.completions.create({...})
);If still errors, check tsconfig.json
12. 认证令牌错误
{
"compilerOptions": {
"moduleResolution": "bundler", // or "node16"
"skipLibCheck": true // Skip type checking for node_modules
}
}
---问题:已设置API密钥但仍出现。
401 Unauthorized原因:环境变量未加载或变量名称错误。
解决方案:
bash
undefined10. CORS Errors with API
.env文件(Next.js)
Problem: errors when calling backend.
Access-Control-Allow-OriginCause: Missing CORS headers in API responses.
Solution:
typescript
// Next.js API Route
export async function POST(req: NextRequest) {
const response = new NextResponse(stream, {
headers: {
"Content-Type": "text/event-stream",
"Access-Control-Allow-Origin": "*", // Or specific domain
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
},
});
return response;
}
// Express
app.use(cors({
origin: "http://localhost:5173", // Your frontend URL
methods: ["POST", "OPTIONS"],
}));THESYS_API_KEY=your_api_key_here
// 验证是否加载
// 在代码中:
if (!process.env.THESYS_API_KEY) {
throw new Error("THESYS_API_KEY is not set");
}
// 对于Vite,客户端使用VITE_前缀
VITE_THESYS_API_KEY=your_key # 客户端
THESYS_API_KEY=your_key # 服务端
// 在Vite中访问
const apiKey = import.meta.env.VITE_THESYS_API_KEY;
// 对于Cloudflare Workers,使用wrangler secrets
npx wrangler secret put THESYS_API_KEY
---11. Rate Limiting Issues
模板与示例
Problem: API calls fail with 429 errors, no retry mechanism.
Cause: No backoff logic for rate limits.
Solution:
typescript
async function callApiWithRetry(apiCall, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await apiCall();
} catch (error) {
if (error.status === 429 && i < maxRetries - 1) {
const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
await new Promise((resolve) => setTimeout(resolve, waitTime));
continue;
}
throw error;
}
}
}
// Usage
const response = await callApiWithRetry(() =>
client.chat.completions.create({...})
);本指南在目录中包含15+可运行模板:
templates/12. Authentication Token Errors
Vite + React(5个模板)
Problem: even with API key set.
401 UnauthorizedCause: Environment variable not loaded or incorrect variable name.
Solution:
bash
undefined- - 带自定义后端的极简C1Chat配置
basic-chat.tsx - - 使用C1Component并手动管理状态
custom-component.tsx - - 网页搜索+数据库查询工具
tool-calling.tsx - - 带深色模式切换的自定义主题
theme-dark-mode.tsx - - 精确的依赖版本
package.json
.env file (Next.js)
Next.js(4个模板)
THESYS_API_KEY=your_api_key_here
- - C1Chat页面组件
app/page.tsx - - 流式API路由处理程序
app/api/chat/route.ts - - 集成工具的API路由
tool-calling-route.ts - - Next.js依赖配置
package.json
Verify it's loaded
Cloudflare Workers(3个模板)
In your code:
—
if (!process.env.THESYS_API_KEY) {
throw new Error("THESYS_API_KEY is not set");
}
- - 带TheSys代理的Hono API
worker-backend.ts - - React前端配置
frontend-setup.tsx - - Worker部署配置
wrangler.jsonc
For Vite, use VITE_ prefix for client-side
共享工具(3个模板)
VITE_THESYS_API_KEY=your_key # Client-side
THESYS_API_KEY=your_key # Server-side
- - 可复用主题配置
theme-config.ts - - 工具通用Zod schema
tool-schemas.ts - - 流式传输辅助函数
streaming-utils.ts
Access in Vite
额外资源
—
参考指南
const apiKey = import.meta.env.VITE_THESYS_API_KEY;
查看目录获取详细指南:
references/- - 所有组件的完整属性参考
component-api.md - - 各AI提供商的分步配置
ai-provider-setup.md - - 全面的工具调用模式
tool-calling-guide.md - - 主题系统深度解析
theme-customization.md - - 扩展错误目录与解决方案
common-errors.md
For Cloudflare Workers, use wrangler secrets
脚本
npx wrangler secret put THESYS_API_KEY
---- - 安装所有所需包
scripts/install-dependencies.sh - - 验证包版本
scripts/check-versions.sh
Templates & Examples
官方文档
This skill includes 15+ working templates in the directory:
templates/- TheSys文档:https://docs.thesys.dev
- C1 Playground:https://console.thesys.dev/playground
- GitHub示例:在GitHub搜索"thesysai"
- Context7:
/websites/thesys_dev
Vite + React (5 templates)
成功指标
- - Minimal C1Chat setup with custom backend
basic-chat.tsx - - Using C1Component with manual state
custom-component.tsx - - Web search + database query tools
tool-calling.tsx - - Custom theming with dark mode toggle
theme-dark-mode.tsx - - Exact dependency versions
package.json
- 令牌节省:比手动实现节省约65-70%
- 避免的错误:12+已记录问题
- 开发速度:提升10倍(来自TheSys数据)
- 用户参与度:83%用户偏好交互式UI
- 包版本:最新稳定版(2025年10月)
Next.js (4 templates)
下一步
- - C1Chat page component
app/page.tsx - - Streaming API route handler
app/api/chat/route.ts - - API route with tool integration
tool-calling-route.ts - - Next.js dependency setup
package.json
- 选择您的框架(Vite+React、Next.js或Cloudflare Workers)
- 从复制相关模板
templates/ - 设置环境变量
THESYS_API_KEY - 运行安装依赖
npm install - 启动开发服务器
- 自定义主题与UI组件
- 添加工具调用实现进阶功能
- 部署到生产环境并配置持久化
如有疑问或问题,请参考指南或查看TheSys官方文档。
references/common-errors.md最后更新:2025-10-26
包版本:@thesysai/genui-sdk@0.6.40
生产环境测试:✅ 是
符合官方标准:✅ 是
Cloudflare Workers (3 templates)
—
- - Hono API with TheSys proxy
worker-backend.ts - - React frontend configuration
frontend-setup.tsx - - Worker deployment config
wrangler.jsonc
—
Shared Utilities (3 templates)
—
- - Reusable theme configurations
theme-config.ts - - Common Zod schemas for tools
tool-schemas.ts - - Helper functions for streaming
streaming-utils.ts
—
Additional Resources
—
Reference Guides
—
See the directory for detailed guides:
references/- - Complete prop reference for all components
component-api.md - - Step-by-step setup for each AI provider
ai-provider-setup.md - - Comprehensive tool calling patterns
tool-calling-guide.md - - Theme system deep dive
theme-customization.md - - Expanded error catalog with solutions
common-errors.md
—
Scripts
—
- - Install all required packages
scripts/install-dependencies.sh - - Verify package versions
scripts/check-versions.sh
—
Official Documentation
—
- TheSys Docs: https://docs.thesys.dev
- C1 Playground: https://console.thesys.dev/playground
- GitHub Examples: Search for "thesysai" on GitHub
- Context7:
/websites/thesys_dev
—
Success Metrics
—
- Token savings: ~65-70% vs manual implementation
- Errors prevented: 12+ documented issues
- Development speed: 10x faster (per TheSys)
- User engagement: 83% prefer interactive UI
- Package versions: Latest stable (Oct 2025)
—
Next Steps
—
- Choose your framework (Vite+React, Next.js, or Cloudflare Workers)
- Copy the relevant template from
templates/ - Set up environment variable
THESYS_API_KEY - Install dependencies with
npm install - Run the development server
- Customize theming and UI components
- Add tool calling for advanced features
- Deploy to production with proper persistence
For questions or issues, refer to the guide or check official TheSys documentation.
references/common-errors.mdLast Updated: 2025-10-26
Package Version: @thesysai/genui-sdk@0.6.40
Production Tested: ✅ Yes
Official Standards Compliant: ✅ Yes
—