co-mono/packages/web-ui
Mario Zechner 4894fa411c Release v0.23.2
Fixed Claude models via GitHub Copilot re-answering all previous prompts.

fixes #209
2025-12-17 17:56:00 +01:00
..
example Release v0.23.2 2025-12-17 17:56:00 +01:00
scripts Updates to prompts 2025-10-17 22:44:03 +02:00
src Simplify compaction: remove proactive abort, use Agent.continue() for retry 2025-12-09 21:43:49 +01:00
package.json Release v0.23.2 2025-12-17 17:56:00 +01:00
README.md docs: fix mini-lit links (#123) 2025-12-06 09:56:31 +01:00
tsconfig.build.json web-ui package 2025-10-05 13:30:08 +02:00
tsconfig.json web-ui package 2025-10-05 13:30:08 +02:00

@mariozechner/pi-web-ui

Reusable web UI components for building AI chat interfaces powered by @mariozechner/pi-ai.

Built with mini-lit web components and Tailwind CSS v4.

Features

  • Modern Chat Interface - Complete chat UI with message history, streaming responses, and tool execution
  • Tool Support - Built-in renderers for calculator, bash, time, and custom tools
  • Attachments - PDF, Office documents, images with preview and text extraction
  • Artifacts - HTML, SVG, Markdown, and text artifact rendering with sandboxed execution
  • Pluggable Transports - Direct API calls or proxy server support
  • Platform Agnostic - Works in browser extensions, web apps, VS Code extensions, Electron apps
  • TypeScript - Full type safety with TypeScript

Installation

npm install @mariozechner/pi-web-ui

Quick Start

See the example directory for a complete working application.

import { Agent, ChatPanel, ProviderTransport, AppStorage,
         SessionIndexedDBBackend, setAppStorage } from '@mariozechner/pi-web-ui';
import { getModel } from '@mariozechner/pi-ai';
import '@mariozechner/pi-web-ui/app.css';

// Set up storage
const storage = new AppStorage({
  sessions: new SessionIndexedDBBackend('my-app-sessions'),
});
setAppStorage(storage);

// Create transport
const transport = new ProviderTransport();

// 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: [],
  },
  transport,
});

// Create chat panel and attach agent
const chatPanel = new ChatPanel();
await chatPanel.setAgent(agent);

document.body.appendChild(chatPanel);

Run the example:

cd example
npm install
npm run dev

Core Components

ChatPanel

The main chat interface component. Displays messages, handles input, and coordinates with the Agent.

import { ChatPanel, ApiKeyPromptDialog } from '@mariozechner/pi-web-ui';

const chatPanel = new ChatPanel();

// Optional: Handle API key prompts
chatPanel.onApiKeyRequired = async (provider: string) => {
  return await ApiKeyPromptDialog.prompt(provider);
};

// Attach an agent
await chatPanel.setAgent(agent);

Agent

Core state manager that handles conversation state, tool execution, and streaming.

import { Agent, ProviderTransport } from '@mariozechner/pi-web-ui';
import { getModel } from '@mariozechner/pi-ai';

const agent = new Agent({
  initialState: {
    model: getModel('anthropic', 'claude-sonnet-4-5-20250929'),
    systemPrompt: 'You are a helpful assistant.',
    thinkingLevel: 'off',
    messages: [],
    tools: [],
  },
  transport: new ProviderTransport(),
});

// Subscribe to events
agent.subscribe((event) => {
  if (event.type === 'state-update') {
    console.log('Messages:', event.state.messages);
  }
});

// Send a message
await agent.send('Hello!');

AgentInterface

Lower-level chat interface for custom implementations. Used internally by ChatPanel.

import { AgentInterface } from '@mariozechner/pi-web-ui';

const chat = new AgentInterface();
await chat.setAgent(agent);

Transports

Transport layers handle communication with AI providers.

ProviderTransport

The main transport that calls AI provider APIs using stored API keys.

import { ProviderTransport } from '@mariozechner/pi-web-ui';

const transport = new ProviderTransport();

const agent = new Agent({
  initialState: { /* ... */ },
  transport,
});

AppTransport

Alternative transport for proxying requests through a custom server.

import { AppTransport } from '@mariozechner/pi-web-ui';

const transport = new AppTransport();

const agent = new Agent({
  initialState: { /* ... */ },
  transport,
});

Tool Renderers

Customize how tool calls and results are displayed.

import { registerToolRenderer, type ToolRenderer } from '@mariozechner/pi-web-ui';
import { html } from '@mariozechner/mini-lit';

const myRenderer: ToolRenderer = {
  renderParams(params, isStreaming) {
    return html`<div>Calling tool with: ${JSON.stringify(params)}</div>`;
  },

  renderResult(params, result) {
    return html`<div>Result: ${result.output}</div>`;
  }
};

registerToolRenderer('my_tool', myRenderer);

Storage

The package provides flexible storage backends for API keys, settings, and session persistence.

AppStorage

Central storage configuration for the application.

import { AppStorage, setAppStorage, SessionIndexedDBBackend } from '@mariozechner/pi-web-ui';

const storage = new AppStorage({
  sessions: new SessionIndexedDBBackend('my-app-sessions'),
});

setAppStorage(storage);

Available Backends

  • LocalStorageBackend - Uses browser localStorage
  • IndexedDBBackend - Uses IndexedDB for larger data
  • SessionIndexedDBBackend - Specialized for session storage
  • WebExtensionStorageBackend - For browser extensions using chrome.storage API

Session Management

import { getAppStorage } from '@mariozechner/pi-web-ui';

const storage = getAppStorage();

// Save session
await storage.sessions?.saveSession(sessionId, agentState, undefined, title);

// Load session
const sessionData = await storage.sessions?.loadSession(sessionId);

// List sessions
const sessions = await storage.sessions?.listSessions();

Styling

The package includes pre-built Tailwind CSS with the Claude theme:

import '@mariozechner/pi-web-ui/app.css';

Or customize with your own Tailwind config:

@import '@mariozechner/mini-lit/themes/claude.css';
@tailwind base;
@tailwind components;
@tailwind utilities;

Dialogs

The package includes several dialog components for common interactions.

SettingsDialog

Settings dialog with tabbed interface for API keys, proxy configuration, etc.

import { SettingsDialog, ApiKeysTab, ProxyTab } from '@mariozechner/pi-web-ui';

// Open settings with tabs
SettingsDialog.open([new ApiKeysTab(), new ProxyTab()]);

SessionListDialog

Display and load saved sessions.

import { SessionListDialog } from '@mariozechner/pi-web-ui';

SessionListDialog.open(async (sessionId) => {
  await loadSession(sessionId);
});

ApiKeyPromptDialog

Prompt user for API key when needed.

import { ApiKeyPromptDialog } from '@mariozechner/pi-web-ui';

const apiKey = await ApiKeyPromptDialog.prompt('anthropic');

PersistentStorageDialog

Request persistent storage permission.

import { PersistentStorageDialog } from '@mariozechner/pi-web-ui';

await PersistentStorageDialog.request();

Platform Integration

Browser Extension

import { AppStorage, WebExtensionStorageBackend, Agent, ProviderTransport } from '@mariozechner/pi-web-ui';

const storage = new AppStorage({
  providerKeys: new WebExtensionStorageBackend(),
  settings: new WebExtensionStorageBackend(),
});
setAppStorage(storage);

Web Application

import { AppStorage, SessionIndexedDBBackend, setAppStorage } from '@mariozechner/pi-web-ui';

const storage = new AppStorage({
  sessions: new SessionIndexedDBBackend('my-app-sessions'),
});
setAppStorage(storage);

Examples

  • example/ - Complete web application with session management
  • sitegeist - Browser extension for AI-powered web navigation

API Reference

See src/index.ts for the full public API.

Known Bugs

  • PersistentStorageDialog: Currently broken and commented out in examples. The dialog for requesting persistent storage does not work correctly and needs to be fixed.

License

MIT