Composable React AI agent — drop an in-app chat, a conversation tree and a
complete settings surface into any React app. The agent loop runs entirely in
the browser on top of pi-agent-core
and pi-ai; your keys and conversations stay on the device.
📖 Documentation · 🧪 Demos · 🚀 Live demo · 📦 npm
- Browser-native agent loop. Requests go straight from the browser to the provider you choose. No backend proxy, no keys on your servers.
- Conversation tree. Fork any session from any message; branches stay linked to their origin and survive deletion of their parent.
- Zero opinions by default. A bare
<ReAgent />is just chat: no built-in tools, skills or MCP servers. Add exactly what your app needs. - Built-in settings. Model, system prompt, skills, tools and MCP servers — a full settings surface out of the box.
- Bring your own provider. OpenRouter (verified for browser use) and any OpenAI-compatible endpoint such as Ollama, LM Studio or vLLM. Other cloud gateways are disabled until verified — see browser support.
- WebMCP aware. If the page exposes tools through
document.modelContext, ReAgent detects them and hands them to the model automatically. - Host-injectable providers. Register your own LLM provider with a custom setup UI; connection details stay in memory only.
- Composable and headless. Use the styled preset, or compose
ReAgentProviderwith the exported UI parts and hooks. - Themeable. Tailwind v4 utilities with zero-specificity design tokens.
- Local-first. API keys and config in
localStorage, conversations inIndexedDB.
# pnpm (default)
pnpm add @liyu1981/reagent
# npm
npm install @liyu1981/reagentPeer dependencies: @earendil-works/pi-agent-core@1.3.0,
@earendil-works/pi-ai@1.3.0, react@^19.2.0, react-dom@^19.2.0.
import { ReAgent } from '@liyu1981/reagent';
export function AgentPanel() {
return (
<div style={{ height: 'min(720px, 80vh)' }}>
<ReAgent surface="glass" theme="dark" />
</div>
);
}Live demos, each with its full source on screen:
- Vanilla — the preset and nothing else.
- Skills, tools & MCP — host-defined skills, a custom tool and the Exa MCP server.
- Filesystem · Attachments — OPFS-backed attachments and tools with a fake, in-page LLM.
- WebMCP — tools registered by the page through WebMCP.
- Host provider — a host-injected provider with its own setup UI.
For the demos that use a real model, ReAgent opens a session and points you at Settings → Model to add an OpenRouter key (the only cloud provider verified for browser use) or a local Ollama URL, then verify the connection. The fake demos work without a key.
ReAgent ships Tailwind utilities. In your global stylesheet, after Tailwind:
@import "tailwindcss";
@import "@liyu1981/reagent/styles.css";
@source "../node_modules/@liyu1981/reagent/dist";Design tokens (--background, --card, --border, --muted-foreground,
--primary, --accent, --destructive, --ring, …) are the theming contract.
The package registers them as Tailwind theme colors and ships low-specificity
fallbacks, so an existing shadcn/ui theme just works.
Every host integration is optional.
| Prop | Type | Default | Purpose |
|---|---|---|---|
surface |
'glass' | 'solid' |
'glass' |
Panel styling. |
theme |
'light' | 'dark' |
'light' |
Theme for markdown/rendering. |
language |
string |
'en' |
Answer language and default copy. |
renderMarkdown |
ComponentType<{ content; theme? }> |
plain <pre> |
Render messages. |
uploadFile |
(file: File) => Promise<string> |
— | Persist a file, return markdown. |
files |
ReAgentFilesConfig | null |
null |
Opt-in durable attachments with preview/download (e.g. createOpfsFileStore). |
notify |
(message, level?) => void |
no-op | Success/error notifications. |
messages / translate |
copy overrides / translator | English | i18n. |
extraTools |
AgentTool<any>[] |
[] |
Raw tools (e.g. MCP). |
extraDescriptors |
AgentToolDescriptor[] |
[] |
Registry tools shown in the Tools panel. |
storagePrefix |
string |
'agent' |
Namespace all persisted state; set per agent to run several on one page. |
draft / editor / selection |
editor integration | — | Let the agent edit an open document. |
onClose / onClearSelection |
callbacks | — | Header/selection hooks. |
See the components reference for the full list.
<ReAgent /> is only one arrangement. Import the provider, UI parts and hooks
to build your own:
import { ReAgentProvider, ReAgentRoot, ReAgentMessageList, useReAgent } from '@liyu1981/reagent';
function CustomChat() {
const { send, status } = useReAgent();
return (
<ReAgentRoot className="flex h-full flex-col">
<ReAgentMessageList className="flex-1" />
<button onClick={() => void send()} disabled={status === 'streaming'}>
Send
</button>
</ReAgentRoot>
);
}
<ReAgentProvider>
<CustomChat />
</ReAgentProvider>;useReAgent() exposes the full runtime (sessions, streaming state, tool calls,
composer state, send/stop, …). Configuration lives in an external store and
works outside React via getAgentConfig / updateAgentConfig.
ReAgent registers the cloud providers verified to work from the browser
(only openrouter today) plus one custom OpenAI-compatible endpoint:
| Provider | Notes |
|---|---|
openrouter |
API key. Verified end-to-end from the browser; Test lists its live model catalog. |
ollama |
Custom local/OpenAI-compatible endpoint (Ollama, LM Studio, vLLM, …); defaults to http://localhost:11434, no key. |
Most AI gateways block direct browser requests (missing CORS headers), so the
rest of pi-ai's providers are disabled until verified or put behind a backend
proxy. See the
browser support table.
Credentials are managed from the settings UI or programmatically:
import { listAvailableModels, saveApiKey, setOllamaBaseUrl, testConnection } from '@liyu1981/reagent';
// Cloud (verified for browser use)
await saveApiKey('openrouter', 'sk-or-…');
await testConnection('openrouter');
// Local OpenAI-compatible endpoint (keyless)
setOllamaBaseUrl('http://localhost:11434');
listAvailableModels();.
├── src/ # the library (@liyu1981/reagent)
├── styles.css # Tailwind entry + design tokens
├── docs/ # documentation markdown (source for the site)
└── site/ # Vite demo + documentation site (GitHub Pages)
The site/ package is a Vite app that powers the live documentation and the
interactive demo. On every push to main,
.github/workflows/deploy-pages.yml
builds the library and the site and publishes site/dist to GitHub Pages.
Enable it once under Settings → Pages → Build and deployment → Source: GitHub Actions.
pnpm install
pnpm build # build the library to dist/
pnpm typecheck # typecheck the library
pnpm site:build # build the library + the site
pnpm site:dev # run the docs/demo site locally (self-signed HTTPS)MIT © Yu Li