Usage
Composition patterns, session navigation, render functions, and ask-user-question.
Usage
Session Navigation
The package does not handle routing — use onSessionCreated to navigate when the first message creates a session:
import { Chat } from "@polpo-ai/chat";
import { useRouter } from "next/navigation";
function NewChatPage() {
const router = useRouter();
return (
<Chat
agent="coder"
onSessionCreated={(id) => router.replace(`/chat/${id}`)}
/>
);
}Render Function Pattern
Use a render function for conditional rendering — show a landing page when there are no messages, then switch to the conversation:
<Chat agent="coder" onSessionCreated={(id) => router.replace(`/chat/${id}`)}>
{({ hasMessages }) =>
hasMessages ? (
<ChatInput placeholder="Type a message..." />
) : (
<LandingPage />
)
}
</Chat>When hasMessages is false and children is a render function, the message list is hidden automatically.
Custom Prompt Input
Pass children to <Chat> to replace the default ChatInput:
<Chat sessionId={id} agent="coder">
<MyCustomInput />
</Chat>Inside any child, use useChatContext() to access chat state:
import { useChatContext } from "@polpo-ai/chat";
function MyCustomInput() {
const { sendMessage, isStreaming, abort, uploadFile } = useChatContext();
// Build your own input...
}Ask-User-Question
When an agent sends an ask_user_question tool call, show the ChatAskUser component:
import { ChatInput, ChatAskUser, useChatContext } from "@polpo-ai/chat";
function ChatInputWithAskUser() {
const { pendingToolCall, sendMessage } = useChatContext();
if (pendingToolCall?.toolName === "ask_user_question") {
return (
<ChatAskUser
questions={pendingToolCall.arguments.questions}
onSubmit={(answers) => sendMessage(JSON.stringify({ answers }))}
/>
);
}
return <ChatInput />;
}Single question renders a flat layout. Multiple questions render a wizard with tabs and summary.
Session List
Show previous conversations with ChatSessionList or grouped by agent with ChatSessionsByAgent:
import { useSessions, useAgents } from "@polpo-ai/react";
import { ChatSessionList } from "@polpo-ai/chat";
function Sidebar() {
const { sessions, isLoading, deleteSession } = useSessions();
const { agents } = useAgents();
return (
<ChatSessionList
sessions={sessions}
agents={agents}
isLoading={isLoading}
activeSessionId={currentId}
onSelect={(id) => router.push(`/chat/${id}`)}
onDelete={deleteSession}
/>
);
}Agent Selector
Let users pick an agent before starting a conversation:
import { useAgents } from "@polpo-ai/react";
import { ChatAgentSelector } from "@polpo-ai/chat";
function AgentPicker() {
const { agents } = useAgents();
const [selected, setSelected] = useState<string>();
return (
<ChatAgentSelector
agents={agents}
selected={selected}
onSelect={setSelected}
fallbackLabel="Auto (Orchestrator)"
/>
);
}Suggestions
Show prompt suggestions on the landing page:
import { ChatSuggestions } from "@polpo-ai/chat";
<ChatSuggestions
suggestions={[
{ icon: <Zap size={14} />, text: "Automate a task" },
{ icon: <BarChart3 size={14} />, text: "Generate a report" },
]}
onSelect={(text) => sendMessage(text)}
columns={2}
/>Custom Tool Renderers
All tool calls are rendered automatically. To customize a specific tool:
import { ToolCallShell } from "@polpo-ai/chat";
import { Database } from "lucide-react";
function ToolDatabaseQuery({ tool }) {
return (
<ToolCallShell tool={tool} icon={Database} label="Query" summary={tool.arguments?.query}>
<pre>{tool.result}</pre>
</ToolCallShell>
);
}