This guide assumes you have basic knowledge of Vercel AI SDK and React.
You’ll also need a Thesys API key from the C1 Console.
- Building an agent
- Building a chatbot
Integrating Thesys C1 with
useCompletion from Vercel AI SDK allows you to easily create
Generative UI based capabilities for your agent. useCompletion enables the streaming of text completions from your AI provider, manages the input state,
and updates the UI automatically as new messages are received.1
Create a new Vercel project
Copy
Ask AI
npx create-next-app@latest thesys-vercel-ai-sdk
2
Initiate the backend endpoint
Copy
Ask AI
npm install --save ai @ai-sdk/openai
app/api/completion/route.ts
Copy
Ask AI
import { streamText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
// Allow streaming responses up to 30 seconds
export const maxDuration = 30;
export async function POST(req: Request) {
const { prompt }: { prompt: string } = await req.json();
const result = streamText({
model: createOpenAI({
apiKey: process.env.THESYS_API_KEY,
baseURL: "https://api.thesys.dev/v1/embed",
}).chat("c1/anthropic/claude-sonnet-4/v-20250815"),
prompt,
});
return result.toUIMessageStreamResponse();
}
3
Render the response
Copy
Ask AI
npm install --save @thesysai/genui-sdk @crayonai/react-ui @crayonai/react-core
app/page.tsx
Copy
Ask AI
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { useState } from "react";
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
export default function Page() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({
api: "/api/chat",
}),
});
const [input, setInput] = useState("");
const handleC1Action = ({ llmFriendlyMessage, humanFriendlyMessage }) => {
sendMessage({
text: llmFriendlyMessage,
metadata: { humanFriendlyMessage },
});
};
return (
<ThemeProvider>
<div className="h-screen flex flex-col">
<div className="flex-1 flex justify-center overflow-auto">
<div className="w-full max-w-3xl p-4">
<div className="space-y-3">
{messages.map((message) => {
const text = message.parts
.filter((part) => part.type === "text")
.map((part) => part.text)
.join("");
return (
<div key={message.id} className="p-3 rounded-lg bg-gray-50">
{message.role === "user" ? (
<div className="text-sm text-gray-700">
{message.metadata?.humanFriendlyMessage || text}
</div>
) : (
<C1Component
isStreaming={status === "streaming"}
c1Response={text}
onAction={handleC1Action}
/>
)}
</div>
);
})}
</div>
</div>
</div>
<div className="p-4">
<div className="max-w-lg mx-auto">
<form
onSubmit={(e) => {
e.preventDefault();
if (input.trim()) {
sendMessage({ text: input });
setInput("");
}
}}
className="flex gap-2"
>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
disabled={status !== "ready"}
placeholder="Say something..."
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button
type="submit"
disabled={status !== "ready"}
className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:opacity-50"
>
Send
</button>
</form>
</div>
</div>
</div>
</ThemeProvider>
);
}
4
Run the app
Copy
Ask AI
export THESYS_API_KEY=<your-api-key>
npm run dev
Integrating Thesys C1 with
useChat from Vercel AI SDK allows you to easily create a conversational user interface.
useChat enables the streaming of chat messages from your AI provider, manages the chat state,
and updates the UI automatically as new messages are received.1
Create a new Vercel project
Copy
Ask AI
npx create-next-app@latest thesys-vercel-ai-sdk
2
Initiate the backend endpoint
Copy
Ask AI
npm install --save ai @ai-sdk/openai
app/api/chat/route.ts
Copy
Ask AI
import { convertToModelMessages, streamText, UIMessage } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
// Allow streaming responses up to 30 seconds
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const model = createOpenAI({
apiKey: process.env.THESYS_API_KEY,
baseURL: "https://api.thesys.dev/v1/embed",
}).chat("c1/anthropic/claude-sonnet-4/v-20250815");
const result = streamText({
model: model,
messages: convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}
3
Render the chat UI
Copy
Ask AI
npm install --save @thesysai/genui-sdk @crayonai/react-ui @crayonai/react-core
app/page.tsx
Copy
Ask AI
"use client";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { useState } from "react";
import { C1Component, ThemeProvider } from "@thesysai/genui-sdk";
import "@crayonai/react-ui/styles/index.css";
export default function Page() {
const { messages, sendMessage, status } = useChat({
transport: new DefaultChatTransport({
api: "/api/chat",
}),
});
const [input, setInput] = useState("");
const handleC1Action = ({ llmFriendlyMessage, humanFriendlyMessage }) => {
sendMessage({
text: llmFriendlyMessage,
metadata: { humanFriendlyMessage },
});
};
return (
<ThemeProvider>
<div className="h-screen flex flex-col">
<div className="flex-1 flex justify-center overflow-auto">
<div className="w-full max-w-3xl p-4">
<div className="space-y-3">
{messages.map((message) => {
const text = message.parts
.filter((part) => part.type === "text")
.map((part) => part.text)
.join("");
return (
<div key={message.id} className="p-3 rounded-lg bg-gray-50">
{message.role === "user" ? (
<div className="text-sm text-gray-700">
{message.metadata?.humanFriendlyMessage || text}
</div>
) : (
<C1Component
isStreaming={status === "streaming"}
c1Response={text}
onAction={handleC1Action}
/>
)}
</div>
);
})}
</div>
</div>
</div>
<div className="p-4">
<div className="max-w-lg mx-auto">
<form
onSubmit={(e) => {
e.preventDefault();
if (input.trim()) {
sendMessage({ text: input });
setInput("");
}
}}
className="flex gap-2"
>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
disabled={status !== "ready"}
placeholder="Say something..."
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button
type="submit"
disabled={status !== "ready"}
className="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:opacity-50"
>
Send
</button>
</form>
</div>
</div>
</div>
</ThemeProvider>
);
}
4
Run the app
Copy
Ask AI
export THESYS_API_KEY=<your-api-key>
npm run dev
View the code
Find more examples and complete code on our GitHub repository.