Documentation Index
Fetch the complete documentation index at: https://mintlify.com/badlogic/pi-mono/llms.txt
Use this file to discover all available pages before exploring further.
The @mariozechner/pi-web-ui package provides reusable web components for building AI chat interfaces powered by the Pi agent runtime.
Key Features
Chat UI
Complete interface with streaming and tool execution
Attachments
PDF, DOCX, XLSX, images with text extraction
Artifacts
Interactive HTML, SVG, Markdown with sandboxed execution
Storage
IndexedDB-backed sessions and settings
Installation
npm install @mariozechner/pi-web-ui @mariozechner/pi-agent-core @mariozechner/pi-ai
Quick Start
import { Agent } from '@mariozechner/pi-agent-core';
import { getModel } from '@mariozechner/pi-ai';
import {
ChatPanel,
AppStorage,
IndexedDBStorageBackend,
setAppStorage,
defaultConvertToLlm,
ApiKeyPromptDialog,
} from '@mariozechner/pi-web-ui';
import '@mariozechner/pi-web-ui/app.css';
// Set up storage
const storage = AppStorage.create();
await storage.init();
setAppStorage(storage);
// Create agent
const agent = new Agent({
initialState: {
systemPrompt: 'You are a helpful assistant.',
model: getModel('anthropic', 'claude-sonnet-4-5-20250929'),
thinkingLevel: 'off',
messages: [],
tools: [],
},
convertToLlm: defaultConvertToLlm,
});
// Create chat panel
const chatPanel = new ChatPanel();
await chatPanel.setAgent(agent, {
onApiKeyRequired: (provider) => ApiKeyPromptDialog.prompt(provider),
});
document.body.appendChild(chatPanel);
Architecture
┌─────────────────────────────────────┐
│ ChatPanel │
│ ┌─────────────────────────────────┐ │
│ │ AgentInterface (messages) │ │
│ │ ArtifactsPanel (HTML/SVG) │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Agent (pi-agent-core) │
│ - State management │
│ - Tool execution │
│ - Event streaming │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ AppStorage │
│ - SettingsStore │
│ - ProviderKeysStore │
│ - SessionsStore │
│ - CustomProvidersStore │
└─────────────────────────────────────┘
Core Components
ChatPanel
High-level chat interface:
const chatPanel = new ChatPanel();
await chatPanel.setAgent(agent, {
onApiKeyRequired: async (provider) => ApiKeyPromptDialog.prompt(provider),
onBeforeSend: async () => { /* save draft */ },
toolsFactory: (agent, agentInterface, artifactsPanel, runtimeProvidersFactory) => [
createJavaScriptReplTool(),
],
});
AgentInterface
Lower-level chat interface for custom layouts:
const chat = document.createElement('agent-interface') as AgentInterface;
chat.session = agent;
chat.enableAttachments = true;
chat.enableModelSelector = true;
chat.onApiKeyRequired = async (provider) => { /* ... */ };
JavaScript REPL
Execute JavaScript in sandboxed environment:
import { createJavaScriptReplTool } from '@mariozechner/pi-web-ui';
const replTool = createJavaScriptReplTool();
agent.setTools([replTool]);
Extract text from documents at URLs:
import { createExtractDocumentTool } from '@mariozechner/pi-web-ui';
const extractTool = createExtractDocumentTool();
extractTool.corsProxyUrl = 'https://corsproxy.io/?';
agent.setTools([extractTool]);
Artifacts
Built into ArtifactsPanel:
const artifactsPanel = new ArtifactsPanel();
artifactsPanel.agent = agent;
agent.setTools([artifactsPanel.tool]);
Storage
AppStorage
Centralized storage management:
const storage = AppStorage.create();
await storage.init();
setAppStorage(storage);
// Settings
await storage.settings.set('proxy.enabled', true);
const enabled = await storage.settings.get<boolean>('proxy.enabled');
// API Keys
await storage.providerKeys.set('anthropic', 'sk-ant-...');
const key = await storage.providerKeys.get('anthropic');
// Sessions
await storage.sessions.save(sessionData, metadata);
const data = await storage.sessions.get(sessionId);
Message Types
UserMessageWithAttachments
User message with files:
const message: UserMessageWithAttachments = {
role: 'user-with-attachments',
content: 'Analyze this document',
attachments: [pdfAttachment],
timestamp: Date.now(),
};
ArtifactMessage
For artifact persistence:
const artifact: ArtifactMessage = {
role: 'artifact',
action: 'create',
filename: 'chart.html',
content: '<div>...</div>',
timestamp: new Date().toISOString(),
};
Styling
Import pre-built CSS:
import '@mariozechner/pi-web-ui/app.css';
Or use with Tailwind:
@import '@mariozechner/mini-lit/themes/claude.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
Next Steps
Components
Explore web UI components
API Reference
Complete API documentation
Example App
View complete example application