co-mono/packages/web-ui
Mario Zechner d2b60f11eb fix: RPC mode session management not saving sessions
Since version 0.9.0, RPC mode (--mode rpc) was not saving messages to
session files. The agent.subscribe() call with session management logic
was only present in the TUI renderer after it was refactored.

RPC mode now properly saves sessions just like interactive mode.

Added test for RPC mode session management to prevent regression.

Fixes #83

Thanks @kiliman for reporting this issue!
2025-12-01 01:19:17 +01:00
..
example chore: sync all versions to 0.6.2 and fix workspace references 2025-11-12 23:44:05 +01:00
scripts Updates to prompts 2025-10-17 22:44:03 +02:00
src Add lifecycle callbacks to SandboxRuntimeProvider for abort signal support 2025-11-16 00:56:20 +01:00
package.json fix: RPC mode session management not saving sessions 2025-12-01 01:19:17 +01:00
README.md Rename ChromeStorageBackend to WebExtensionStorageBackend for cross-browser support 2025-10-06 23:48:43 +02: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