useChat DX cleanup
@baleybots/react useChat is client-only again. Server-mode options and useGroupChat were removed — not deprecated behind flags.
What was removed
| Removed | Replacement |
|---|---|
useGroupChat | Client useChat for browser chat; hosted crew UI uses /api/chat + useCrewSessions |
apiUrl, chatId, multiAgent, agents | Client useChat with model + optional storage; hosted crew chat via product /api/chat |
loadHistory, isResuming | History via storage on client; server persistence in your route handler |
pendingApproval, approveToolCall, rejectToolCall | pendingApprovals + respondToToolApprovals (batch) |
SendStreamingOptions | Plain sendStreaming(content) |
Primary messages rendering | segments + ChatTurns / ChatTurn |
Hook messages still exists (derived via deriveUIMessages) for backward compatibility — do not build new UIs on it.
Migration
From useGroupChat / server-mode useChat
// Before — removed
import { useGroupChat } from '@baleybots/react';
const { messages, sendMessage } = useGroupChat({
apiUrl: 'https://your-api.com/chat',
chatId: 'conversation-123',
});
// After — client-side chat in the browser
import { useChat, ChatTurns, ChatTurn } from '@baleybots/react';
import { openai } from '@baleybots/core';
const { segments, sendStreaming } = useChat({
model: openai('gpt-5.6-luna'),
systemPrompt: 'You are a helpful assistant',
});
// Render
<ChatTurns segments={segments}>
{(turn) => <ChatTurn key={turn.id} turn={turn} />}
</ChatTurns>
For multi-agent crew chat in the Baleybots product UI, connect to the host /api/chat endpoint and consume SSE with useCrewSessions — do not point useChat at a backend URL.
For your own server with tools, use createChatRoute from @baleybots/proxy-server (session HistoryStorage + bot-route mux) or createBotRoute for a single-shot Processable, with a fetch-based client — not removed useChat server mode. See Chat with Tools.
From messages to ChatTurns
// Before
{messages.map((msg) => (
<div key={msg.id}>
<b>{msg.role}:</b> {msg.content}
</div>
))}
// After
import { useChat, ChatTurns, ChatTurn } from '@baleybots/react';
const { segments } = useChat({ model: 'openai|gpt-5.6-luna' });
<ChatTurns segments={segments}>
{(turn) => <ChatTurn key={turn.id} turn={turn} />}
</ChatTurns>
From scalar approvals to batch approvals
// Before — removed
const { pendingApproval, approveToolCall, rejectToolCall } = useChat({ tools });
// After
const { pendingApprovals, respondToToolApprovals } = useChat({ tools });
if (pendingApprovals.length > 0) {
respondToToolApprovals(
pendingApprovals.map((p) => ({ approvalId: p.approvalId, approved: true })),
);
}
Submit exactly one decision per entry in pendingApprovals before the turn resumes.
Legacy UIChatMessage[] consumers
If another hook or analytics layer still needs OpenAI-shaped rows:
import { deriveUIMessages } from '@baleybots/core';
const messages = deriveUIMessages(segments);
Key differences (summary)
| Old pattern | New pattern |
|---|---|
useGroupChat + apiUrl | Client useChat or host /api/chat |
messages.map(...) | ChatTurns + ChatTurn |
sendMessage | sendStreaming or send |
pendingApproval / approveToolCall() | pendingApprovals / respondToToolApprovals([...]) |
multiAgent + agents | Crew UI / orchestration layer (out of scope for useChat) |