Telygent

UI SDK

Ship AI chat UI in minutes

The Telygent UI SDK is a collection of accessible, customizable components designed to bridge the gap between your backend SDK and a polished user experience. It follows the shadcn/ui philosophy: it doesn't just install a library; it grafts the source code into your project so you have total control over the styling and behavior.

Installation & Setup

Initialize your project and pull in the core chat components using the CLI. This will scaffold the necessary providers, hooks, and UI elements into your components/ai folder.

terminal
1# Initialize the UI registry 2npx telygent-ui setup 3 4# OPTIONAL: Add the chat interface components 5npx telygent-ui add chat-interface

Adapter pattern

To keep the UI framework-agnostic, the ChatInterface uses a Frontend Adapter. This allows you to connect the UI to any backend endpoint whether you are using the Telygent Node.js SDK, a custom Python backend, or a serverless function.

Core responsibilities:

sendMessageStream

Use this for a premium user experience. As the AI "thinks" and types, the UI SDK renders fragments of text and status updates in real-time. This reduces "perceived latency" significantly for long-running analytical queries.

Instead of a standard function, you provide an AsyncIterable viasendMessageStream. The UI SDK iterates over the stream events.

sendMessage

Use this if you prefer a simpler backend implementation or if your AI responses are typically very short. The UI will show a "loading" state until the entire response is ready.

The adapter waits for a single Promise to resolve. Once received, the UI renders the full markdown content and any associated visualizations at once.

getHistory

Hydrates the chat window with previous messages when a user returns to a conversation.

Standard setup

ChatPage.tsx
1import {ChatProvider, type SendMessageInput, type SendMessageResult, type ChatMessage} from "@/components/ai/ChatProvider"; 2import {ChatInterface} from "@/components/ai/ChatInterface"; 3 4const adapter = { 5 async sendMessage({message, conversationId}: SendMessageInput): Promise<SendMessageResult> { 6 const response = await api.send({message, conversationId}); 7 return { 8 conversationId: response.conversationId, 9 message: { 10 role: "assistant", 11 content: response.content, 12 createdAt: new Date(), 13 visualizations: response.visualizations, 14 }, 15 }; 16 }, 17 async getHistory(conversationId: string): Promise<ChatMessage[]> { 18 const history = await api.history(conversationId); 19 return history.messages.map((item) => ({ 20 role: item.role === "assistant" ? "assistant" : "user", 21 content: item.content, 22 createdAt: new Date(item.timestamp), 23 visualizations: item.visualizations ?? [], 24 })); 25 }, 26}; 27 28export default function Page() { 29 return ( 30 <ChatProvider adapter={adapter}> 31 <ChatInterface conversationId="conv_123" aiName="Telygent" /> 32 </ChatProvider> 33 ); 34}

Streaming setup

ChatPage.tsx
1 import { 2 ChatProvider, 3 type SendMessageInput, 4 type ChatStreamEvent, 5 type ChatMessage, 6 } from "@/components/ai/ChatProvider"; 7 import {ChatInterface} from "@/components/ai/ChatInterface"; 8 9 async function* streamChat(input: SendMessageInput): AsyncIterable<ChatStreamEvent> { 10 const response = await fetch("/api/chat/stream", { 11 method: "POST", 12 headers: {"Content-Type": "application/json"}, 13 body: JSON.stringify({ 14 question: input.message, 15 conversationId: input.conversationId, 16 }), 17 }); 18 19 const reader = response.body!.getReader(); 20 const decoder = new TextDecoder(); 21 let buffer = ""; 22 23 while (true) { 24 const {value, done} = await reader.read(); 25 if (done) break; 26 27 buffer += decoder.decode(value, {stream: true}); 28 const lines = buffer.split("\n\n"); 29 buffer = lines.pop() ?? ""; 30 31 for (const line of lines) { 32 if (!line.startsWith("data: ")) continue; 33 const payload = JSON.parse(line.replace("data: ", "")) as ChatStreamEvent; 34 yield payload; 35 } 36 } 37 } 38 39 const adapter = { 40 sendMessageStream: streamChat, 41 async getHistory(conversationId: string): Promise<ChatMessage[]> { 42 const history = await api.history(conversationId); 43 return history.messages.map((item) => ({ 44 role: item.role === "assistant" ? "assistant" : "user", 45 content: item.content, 46 createdAt: new Date(item.timestamp), 47 visualizations: item.visualizations ?? [], 48 })); 49 }, 50 }; 51 52 export default function Page() { 53 return ( 54 <ChatProvider adapter={adapter}> 55 <ChatInterface conversationId="conv_123" aiName="Telygent" /> 56 </ChatProvider> 57 ); 58 }

Adapter fields

conversationId

A unique identifier for your current conversation and to maintain context.

aiName

Optional

A brand or user friendly name you will like the AI to respond as

logo

Optional
Your AI or brand logo for personalization to your UI

description

Optional
A landing page description shown in the chat area when there is no message in the timeline

defaultPrompts

Optional
An array of default questions a user can choose from to get a conversation started with the AI

Placeholder

Optional
Customize the placeholder of the chat input text area

Styling & Markdown Rendering

The Telygent UI SDK uses a custom CSS manifest (ai-mdx.css) to handle the typography and layout of AI-generated content. Without this file, standard HTML elements (like <table> or <ul>) may appear unstyled or broken within the chat bubbles.

You have two options for integrating these styles into your project. Choose the one that best fits your existing workflow.

Option A: The CSS Global Import

Add the @import rule to the top of your main Tailwind or CSS entry point. This ensures the styles are bundled with your global CSS and are available across all routes.

globals.css
1/* Ensure this path matches your local project structure after running 'npx telygent-ui add' */ 2@import "@/components/ai/components/ai-mdx.css"; 3 4@tailwind base; 5@tailwind components; 6@tailwind utilities;

Option B: The CSS Global Import

If you prefer to keep your CSS file clean, you can import the stylesheet directly into your top-level Layout or Page file.

layout.tsx or _app.tsx
1import "@/components/ai/components/ai-mdx.css"; 2import "./globals.css"; 3 4export default function RootLayout({ children }) { 5 return ( 6 <html lang="en"> 7 <body>{children}</body> 8 </html> 9 ); 10}