@ensembleapp/client-sdk
v0.0.56
Published
React client SDK for chat functionality
Downloads
585
Readme
Client SDK
A simple React library for chat functionality with built-in AI SDK integration.
Installation
npm install @ensembleapp/client-sdkUsage
Option 1: Use the pre-built ChatWidget
import { ChatWidget } from '@ensembleapp/client-sdk'
function App() {
return (
<ChatWidget
api={{
baseUrl: '/api',
token: 'your-jwt-token',
}}
threadId="user-123"
agentId="agent-234"
onMessage={(message) => console.log('New message:', message)}
onError={(error) => console.error('Chat error:', error)}
placeholder="Ask me anything..."
welcomeMessage="Hello! How can I help you today?"
/>
)
}Option 2: Build your own UI with the useChat hook
import { useChat } from '@ensembleapp/client-sdk'
function CustomChat() {
const { messages, isLoading, sendMessage } = useChat({
api: {
baseUrl: '/api',
token: 'your-jwt-token',
},
threadId: 'user-123',
agentId="agent-234",
})
return (
<div>
{messages.map(message => (
<div key={message.id}>
<strong>{message.role}:</strong> {message.content}
</div>
))}
<button onClick={() => sendMessage({ text: 'Hello!' })}>
Send Message
</button>
</div>
)
}Reading token usage
The server streams token/usage stats as a data-usage part. You can read them
three ways.
1. <ChatWidget>: the onUsage callback
import { ChatWidget, type ChatUsageData } from '@ensembleapp/client-sdk'
<ChatWidget
api={{ baseUrl: '/api', token: 'your-jwt-token' }}
agentId="agent-234"
threadId="user-123"
onUsage={(usage: ChatUsageData) => {
console.log(usage.inputTokens, usage.outputTokens)
console.log(usage.totalMessageCount, usage.messageHistoryLimit)
}}
/>Or, to render the built-in counter (↑ N in · ↓ N out) above the input without
writing any code, set showTokenUsage:
<ChatWidget api={/* ... */} agentId="..." threadId="..." showTokenUsage />2. useChat hook: the usage return value
usage is reactive state (the latest turn), so it's the simplest way to render:
import { useChat, type ChatUsageData } from '@ensembleapp/client-sdk'
function CustomChat() {
const { messages, sendMessage, usage } = useChat({ /* ...config */ })
// ^^^^^ ChatUsageData | null
return <div>{usage && `${usage.inputTokens} in / ${usage.outputTokens} out`}</div>
}You can also pass onUsage to the hook if you prefer the event style.
3. extractUsageData: for custom stream handling
If you handle the stream at a lower level (e.g. via onData), pull usage out of
any data part:
import { extractUsageData } from '@ensembleapp/client-sdk'
onData: (dataPart) => {
const usage = extractUsageData(dataPart) // ChatUsageData | null
if (usage) { /* ... */ }
}ChatUsageData shape
interface ChatUsageData {
inputTokens: number
outputTokens: number
maxInputTokens?: number
maxOutputTokens?: number
inputTokensPercent?: number
outputTokensPercent?: number
totalMessageCount?: number
messageHistoryLimit?: number
}API Reference
ChatWidget Props
api({ baseUrl: string; token: string; headers? }): Base URL for the chat API, required auth token (sent asAuthorization: Bearer <token>), and optional extra headersthreadId(string): Thread/session ID (required)onMessage?(function): Callback when a new message is receivedonError?(function): Callback when an error occursonFinish?(function): Callback when a conversation finishesonUsage?((usage: ChatUsageData) => void): Callback with token/usage stats as they streamonData?((dataPart) => void): Callback for every raw stream data partshowTokenUsage?(boolean): Show the built-in input/output token counter above the input (default: false)className?(string): Additional CSS classesplaceholder?(string): Input placeholder textwelcomeMessage?(string): Initial welcome message
useChat Hook
const {
messages, // Array of chat messages
status, // Current request status
sendMessage, // Function to send a message
stop, // Function to stop current request
setMessages, // Function to manually set messages
usage, // ChatUsageData | null (latest token/usage stats)
} = useChat(config)