Files
PiAgentUI/README.md
T

8.8 KiB

PiAgentUI chat workspace: session list on the left, a Markdown answer with a JSON block in the middle and the MCP servers panel on the right

What it is

PiAgentUI is a chat UI and workspace for the Pi coding agent. It runs as a web app served by a Pi extension or as a Tauri 2 desktop app, and shows in one window what a bare terminal hides: the session list, tool calls, MCP servers, skills and context usage.

  • Streams real Pi sessions over SSE (/global/event) and renders Markdown, code (Shiki) and math (KaTeX).
  • Shows tool calls as cards and the context usage of the active session.
  • Switches models using the capabilities the runtime reports.
  • Lists configured MCP servers (transport, command, URL, source) and effective skills grouped by source.
  • Exposes built-in and dynamic slash commands, plus Git controls in the composer.
  • Embeds a terminal (xterm.js) and a file explorer next to the chat.
  • Accepts voice input through an OpenAI-compatible STT endpoint set in settings.
  • UI locales: en, pt-BR, es, zh-CN, hi, bn, ar (src/locales/).

Why use it

PiAgentUI does not keep its own agent state. Sessions, models, tools, skills and commands come from the Pi runtime through the extension, so what you see is what Pi is running.

Do not use it if you do not run Pi: without the extension the UI only shows the server connection dialog. It also handles one runtime per window and has no hosted demo or published npm package.

How it works

  • extensions/piagentui-server.ts is the Pi extension. It serves the built UI from dist/ over Node http + ws and injects window.PI_BOOT_DATA (base URL and token).
  • On start it listens on port 58785 (or the next free one) and writes the port and a random token to ~/.pi/agent/piagentui-port.json.
  • GET /global/health is open; other /api/* routes require Authorization: Bearer <token>. The socket binds 0.0.0.0, but each request is checked against loopback unless the LAN toggle at /api/network/access is on (off by default).
  • The Tauri app reads the same discovery file through get_pi_agent_connection, so the desktop build connects to the local runtime without manual setup.
  • In containers, the Rust router (src-router/, axum) sits behind Caddy as the gateway in front of the frontend and backend services.

Quickstart

Tool Version Needed for
Node.js >=22 (.tool-versions: 22.22.0) everything
npm bundled with Node everything (package-lock.json)
Rust 1.85.0 (.tool-versions) desktop app and gateway router
Docker Compose any recent container stack only
Pi Agent installed locally real sessions and models
git clone https://git.evandro.dev.br/evandro/PiAgentUI.git
cd PiAgentUI
npm ci          # postinstall runs scripts/copy-material-icons.mjs
npm run build   # tsc -b && vite build -> dist/
npm run dev     # Vite dev server on http://localhost:5173

npm run dev is front end only: it proxies /api to 127.0.0.1:4096 with the prefix stripped. For the Pi flow, build first and let the extension serve dist/ (Pi loads this repository as a package through the pi.extensions field of package.json):

npm run build
cat ~/.pi/agent/piagentui-port.json   # {"port": 58785, "token": "..."}
# open http://127.0.0.1:58785

Desktop and Android:

npm run tauri dev                 # desktop window on the Vite dev server
npm run tauri build               # bundles: nsis, dmg, deb (src-tauri/tauri.conf.json)
npm run tauri android dev         # see scripts/dev-android.sh

Before a PR, npm run validate runs typecheck, extension typecheck, lint, build and tests; it is the gate CI runs in build.yml.

Configuration

The container stack is inherited from the OpenCodeUI deployment. Copy .env.example to .env first.

File Command What it does
docker-compose.yml docker compose up -d Full stack: gateway (Caddy + Rust router, 127.0.0.1:6658 and 6659), frontend, backend (opencode serve, 4096, 4G memory limit).
docker-compose.standalone.yml docker compose -f docker-compose.standalone.yml up -d Front end only, for an existing opencode serve. Uses BACKEND_URL (default host.docker.internal:4096) and PORT (default 3000).
docker-compose.host.yml docker compose -f docker-compose.yml -f docker-compose.host.yml up -d Optional override: backend runs privileged with the Docker socket and host / mounted at /host.
docker-compose.build.yml docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build Optional override: builds gateway, frontend and backend locally from docker/.
Environment variables (container stack only)
Variable Required Description
ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY, XAI_API_KEY At least one LLM provider keys passed to the backend container.
GATEWAY_PORT No (6658) Host port of the unified entry point.
PREVIEW_PORT No (6659) Host port of the preview entry point.
PREVIEW_DOMAIN No Separate domain for previews; the reverse proxy forwards it to PREVIEW_PORT.
WORKSPACE No (./workspace) Host directory mounted at /workspace in the backend.
OPENCODE_SERVER_PASSWORD Public deployments Password for the backend and the router.
OPENCODE_SERVER_USERNAME No (opencode) Username paired with the password above.
PUBLIC_BASE_URL No Public base URL used by the router built into the gateway.
ROUTER_SCAN_INTERVAL No (5) Router scan interval.
ROUTER_TOKEN_LENGTH No (12) Length of the generated route tokens.
ROUTER_PORT_RANGE No (3000-9999) Port range the router handles.
ROUTER_EXCLUDE_PORTS No (4096) Ports the router skips.
DOCKER_API_VERSION No (1.40) Docker API version for the backend; set in docker-compose.yml, not in .env.example.
USE_CHINA_MIRROR No (1) Backend image build option: use the mirror sources below.
APT_MIRROR, APT_SECURITY_MIRROR, NPM_CONFIG_REGISTRY, NODEJS_ORG_MIRROR, PIP_INDEX_URL, PIP_TRUSTED_HOST No Mirrors for the backend toolchain.
MISE_INSTALL_URL, OPENCODE_INSTALL_URL No Installer URLs used when building the backend image.

Project status

Beta, pre-1.0 (0.6.10), maintained by one developer. Releases are built by release.yml on v* tags (Windows, macOS, Linux and Android artifacts); deploy.yml publishes the web build with VITE_BASE_PATH=/PiAgentUI/.

  • OpenCodeUI naming is only partly cleaned: the Rust router crate is opencodeui-router, images are opencodeui-*, Android APKs are named OpenCodeUI-*, .env.example comments are in Chinese, and the Docker backend runs opencode serve, which belongs to the inherited deployment, not to the Pi extension flow.
  • docker-compose.yml and docker-compose.standalone.yml still pull the upstream ghcr.io/lehhair/opencodeui-frontend image.
  • Tests are component- and server-level (Vitest). There are no tests for the Tauri shell or the Rust router beyond compilation, no end-to-end browser test and no coverage threshold.
  • Voice input needs an OpenAI-compatible STT endpoint and has no automated browser test.

Issues and pull requests go to the issue tracker; run npm run validate before a PR.

License

GPL-3.0-only, see LICENSE. PiAgentUI is a fork and rework of OpenCodeUI; the original author is credited in src-tauri/Cargo.toml.