Skip to main content
A complete chat application built with React, Vite, and the Polpo React SDK. Features streaming responses, session history, agent selection, tool call display, and dark/light theme.

Quick start

# Install dependencies
npm install

# Configure
cp .env.example .env.local
# Edit .env.local with your API key

Environment variables

VariableDescriptionDefault
VITE_POLPO_URLPolpo API URL (leave empty to use proxy)
VITE_POLPO_API_KEYYour project API key
VITE_POLPO_AGENTDefault agent name (optional)

Run locally

# Set your API key in .env.local and run
npm run dev

What’s included

Polpo React SDK integration

The app uses PolpoProvider for context and hooks for data:
import { PolpoProvider } from "@polpo-ai/react";

<PolpoProvider baseUrl={BASE_URL} apiKey={API_KEY} autoConnect={false}>
  <App />
</PolpoProvider>

Agent selection

On first load, the app fetches available agents using useAgents() and displays a selector:
const { agents } = useAgents();

// Renders a list of agents to choose from
{agents.map((a) => (
  <button onClick={() => setSelectedAgent(a.name)}>
    {a.name}
  </button>
))}

Streaming chat completions

The app uses the useChat hook from the React SDK, which handles streaming, session management, and abort automatically:
import { useChat } from "@polpo-ai/react";

const { messages, sendMessage, isStreaming, abort, sessionId } = useChat({
  agent: selectedAgent,
});

// Send a message — streaming and session tracking happen automatically
sendMessage("Explain the auth module");
useChat manages the session ID internally. The first message creates a new session, and subsequent messages continue the same conversation automatically. You can call newSession() to start fresh.
For lower-level control, you can also use chatCompletionsStream() directly from the client SDK:
const { client } = usePolpo();

const stream = client.chatCompletionsStream({
  messages: history,
  stream: true,
  agent: selectedAgent,
  sessionId: sessionId, // required to continue a conversation
});

for await (const chunk of stream) {
  const delta = chunk.choices?.[0]?.delta?.content;
  // Append delta to the current message
}
When using chatCompletionsStream directly, you must capture and pass the session ID yourself. Without sessionId, every request creates a new session.

Session history

Sessions are loaded from the server using useSessions():
const { sessions, getMessages, deleteSession } = useSessions();

// Load a previous session
const msgs = await getMessages(sessionId);

// Delete a session
await deleteSession(sessionId);
The sidebar shows all past sessions with agent name and date.

Tool calls

When the agent executes tools (bash, read, write, etc.), tool call events appear as collapsible blocks showing the tool name, arguments, and result:
const tc = choice.tool_call;
if (tc) {
  // Add to message's toolCalls array
}

Abort / Stop

Streaming can be stopped at any time using the Stop button, which calls stream.abort().

Customization

Change the proxy target

Edit vite.config.ts to point to a different server:
const API_TARGET = process.env.POLPO_PROXY_TARGET ?? "http://api.polpo.localhost";

Add more features

The example is intentionally minimal. You can extend it with:
  • File references — using file content parts with workspace paths
  • Approval gates — using useApprovals() hook
  • Task monitoring — using useTasks() and useMissions() hooks
  • Vault credentials — using useVaultEntries() hook
All hooks are available from @polpo-ai/react. See the React SDK docs for the full API.