Build a Chatbot
This guide shows a minimal React chatbot using @uclaw/sdk/react. useApp manages the app's agent directory; useAgent streams chat for the selected agent.
Prerequisites
Follow React Getting Started and create a backend endpoint that returns a short-lived client token.
Implementation
Create ChatBot.tsx:
tsx
import { useApp, useAgent } from "@uclaw/sdk/react";
import { useState } from "react";
function ActiveChat({ agentId }: { agentId: string }) {
const [input, setInput] = useState("");
const { chat, status } = useAgent({ agentId });
function handleSubmit(event: React.FormEvent) {
event.preventDefault();
if (!input.trim() || chat.isStreaming) return;
chat.sendMessage({
role: "user",
parts: [{ type: "text", text: input.trim() }],
});
setInput("");
}
return (
<div className="chat-container">
<header className="chat-header">
<h3>UClaw Chatbot</h3>
<span className={`status-badge ${status}`}>{status}</span>
</header>
<div className="chat-history">
{chat.messages.map((message) => {
const text = message.parts
.filter((part) => part.type === "text")
.map((part) => part.text)
.join("");
return (
<div key={message.id} className={`chat-message ${message.role}`}>
<strong>{message.role === "user" ? "You" : "AI"}:</strong>
<p>{text}</p>
</div>
);
})}
{chat.isStreaming && <div className="loading">Agent is typing...</div>}
</div>
<form onSubmit={handleSubmit} className="chat-input-form">
<input
value={input}
onChange={(event) => setInput(event.target.value)}
placeholder="Ask a question..."
disabled={chat.isStreaming}
/>
<button type="submit" disabled={chat.isStreaming}>
Send
</button>
</form>
</div>
);
}
export function ChatBot() {
const [agentId, setAgentId] = useState<string | null>(null);
const { createAgent } = useApp({});
async function startChat() {
const agent = await createAgent({
title: "Chatbot",
config: {
instructions: "You are a helpful chatbot.",
modelTier: "fast",
},
});
setAgentId(agent.id);
}
if (!agentId) {
return <button onClick={startChat}>Start chat</button>;
}
return <ActiveChat agentId={agentId} />;
}Styling
css
.chat-container {
display: flex;
flex-direction: column;
height: 500px;
max-width: 600px;
margin: 0 auto;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.chat-header {
padding: 1rem;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
justify-content: space-between;
}
.chat-history {
flex: 1;
overflow-y: auto;
padding: 1rem;
}
.chat-message {
margin-bottom: 1rem;
}
.chat-message.user {
text-align: right;
}
.chat-input-form {
display: flex;
padding: 1rem;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.chat-input-form input {
flex: 1;
padding: 0.5rem;
}Now you have a streaming chatbot connected to a stateful UClaw agent.