AI
useUranusChat
Hook que envolve useChat do @ai-sdk/react, normaliza status e expõe attachments e modos.
useUranusChat é a única integração que o pacote oferece com o Vercel AI SDK. Ele:
- Envolve
useChatde@ai-sdk/react(peer dependency). - Normaliza o status para
idle | submitted | thinking | searching | streaming | error. - Transforma
UIMessageemUranusMessagecomtext,reasoning,toolCalls,citationseattachmentsjá agrupados. - Mantém o estado de
attachmentsindependente das mensagens — só vai junto nosendMessage. - Propaga
mode(chat | plan | research) viabodypara a sua route handler.
tsx
'use client';
import { Chat, useUranusChat } from '@uranus-workspace/ai';
export function ChatPage() {
const chat = useUranusChat({ api: '/api/chat' });
return (
<Chat
messages={chat.messages}
status={chat.status}
mode={chat.mode}
onModeChange={chat.setMode}
onSend={({ text, attachments }) =>
chat.sendMessage({ text, attachments })
}
onStop={chat.stop}
onRegenerate={chat.regenerate}
/>
);
}'use client';
import { CodeBlock } from '@uranus-workspace/ai';
const code = `'use client';
import { Chat, useUranusChat } from '@uranus-workspace/ai';
export function ChatPage() {
const chat = useUranusChat({ api: '/api/chat' });
return (
<Chat
messages={chat.messages}
status={chat.status}
mode={chat.mode}
onModeChange={chat.setMode}
onSend={({ text, attachments }) =>
chat.sendMessage({ text, attachments })
}
onStop={chat.stop}
onRegenerate={chat.regenerate}
/>
);
}`;
export default function UseUranusChatDefault() {
return (
<div className="mx-auto w-full max-w-3xl">
<CodeBlock language="tsx" code={code} />
</div>
);
}
Setup
'use client';
import { useUranusChat } from '@uranus-workspace/ai';
const chat = useUranusChat({
api: '/api/chat',
defaultMode: 'chat',
body: { workspaceId },
});Retorno
{
messages: UranusMessage[];
status: UranusChatStatus; // 'idle' | 'submitted' | 'thinking' | 'searching' | 'streaming' | 'error'
mode: UranusChatMode; // 'chat' | 'plan' | 'research'
setMode: (mode: UranusChatMode) => void;
sendMessage: (input: { text: string; attachments?: UranusAttachment[] }) => void;
stop: () => void;
regenerate: () => void;
error?: Error;
}Server route
import { streamText } from 'ai';
export async function POST(req: Request) {
const { messages, mode } = await req.json();
const system =
mode === 'plan'
? 'Você é um planejador. Retorne stages.'
: mode === 'research'
? 'Você é um pesquisador. Cite fontes.'
: 'Você é o assistente Uranus.';
return streamText({ model: 'anthropic/claude-sonnet-4', system, messages }).toUIMessageStreamResponse();
}Por que normalizar?
useChat retorna status: 'submitted' | 'streaming' | 'ready' | 'error'. Para a UI de chat, submitted precisa virar "Pensando…" e streaming durante uma tool-call precisa virar "Pesquisando…". O hook faz esse mapeamento olhando os parts da mensagem mais recente.