Chat client SDK examples
Small, copy-ready snippets for the chat client SDK guide. Based on the Cloudflare Agents documentation (Client SDK, Chat agents); check there for the latest API.
Minimal React chat
tsx
import { useAgent } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";
export function Chat({ userId }: { userId: string }) {
const agent = useAgent({ agent: "ChatAgent", name: userId });
const { messages, sendMessage, status, stop } = useAgentChat({ agent });
return (
<>
{messages.map((m) => (
<p key={m.id}><b>{m.role}:</b> {m.parts.map((p) => (p.type === "text" ? p.text : "")).join("")}</p>
))}
<form onSubmit={(e) => { e.preventDefault(); const i = e.currentTarget.q; sendMessage({ text: i.value }); i.value = ""; }}>
<input name="q" />
{status === "streaming" ? <button type="button" onClick={stop}>Stop</button> : <button disabled={status !== "ready"}>Send</button>}
</form>
</>
);
}Auth token on connect
ts
const agent = useAgent({
agent: "ChatAgent",
name: userId,
query: async () => ({ token: await getToken() }),
queryDeps: [userId],
cacheTtl: 55 * 60 * 1000, // refresh before a 1-hour token expires
});Check the token in the agent's onConnect (or in your Worker before routing) and close the connection if it is invalid.
Vue (no React)
ts
import { useChat } from "@ai-sdk/vue";
import { AgentClient } from "agents/client";
import { WebSocketChatTransport } from "agents/chat/transport";
const agent = new AgentClient({ agent: "ChatAgent", name: userId, host: location.host });
const { messages, sendMessage, status } = useChat({ transport: new WebSocketChatTransport({ agent }) });Client-side tool (browser location)
ts
useAgentChat({
agent,
onToolCall: async ({ toolCall, addToolOutput }) => {
if (toolCall.toolName !== "getLocation") return;
const pos = await new Promise<GeolocationPosition>((ok, no) => navigator.geolocation.getCurrentPosition(ok, no));
addToolOutput({ toolCallId: toolCall.toolCallId, output: { lat: pos.coords.latitude, lng: pos.coords.longitude } });
},
});Approve or reject a tool call
tsx
import { getToolApproval, getToolPartState } from "@cloudflare/ai-chat/react";
function Approval({ part, respond }) {
const a = getToolApproval(part);
if (getToolPartState(part) !== "waiting-approval" || !a) return null;
return (
<>
<button onClick={() => respond({ id: a.id, approved: true })}>Approve</button>
<button onClick={() => respond({ id: a.id, approved: false })}>Reject</button>
</>
);
}
// <Approval part={part} respond={addToolApprovalResponse} />Extra data per message
ts
// client
useAgentChat({ agent, body: () => ({ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone }) });
// server, inside onChatMessage(_onFinish, options)
const { timezone } = options?.body ?? {};One-off HTTP call
ts
import { agentFetch } from "agents/client";
const res = await agentFetch(
{ agent: "ReportAgent", name: "daily", host: "my-worker.example.workers.dev" },
{ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ run: true }) },
);Source: Cloudflare Agents documentation (developers.cloudflare.com), summarized in our own words by implemented.stream. Last checked 2026-10-17.