9.2 KiB
O que é
PiAgentUI é uma interface de chat e um workspace para o agente de código Pi. Roda como app web servido por uma extensão do Pi ou como app desktop em Tauri 2, e mostra numa janela o que o terminal cru esconde: a lista de sessões, as tool calls, os servidores MCP, as skills e o uso de contexto.
- Faz streaming das sessões reais do Pi por SSE (
/global/event) e renderiza Markdown, código (Shiki) e matemática (KaTeX). - Mostra tool calls como cards e o uso de contexto da sessão ativa.
- Troca de modelo usando as capacidades que o runtime informa.
- Lista os servidores MCP configurados (transporte, comando, URL, origem) e as skills efetivas agrupadas por origem.
- Expõe slash commands nativos e dinâmicos, além de controles de Git no composer.
- Embute um terminal (xterm.js) e um explorador de arquivos ao lado do chat.
- Aceita entrada de voz por um endpoint de STT compatível com OpenAI configurado nas settings.
- Idiomas da interface:
en,pt-BR,es,zh-CN,hi,bn,ar(src/locales/).
Por que usar
O PiAgentUI não guarda estado próprio do agente. Sessões, modelos, tools, skills e comandos vêm do runtime do Pi pela extensão, então o que aparece na tela é o que o Pi está rodando.
Não use se você não roda o Pi: sem a extensão, a interface mostra só o diálogo de conexão com o servidor. Ele também atende um runtime por janela e não tem demo hospedada nem pacote publicado no npm.
Como funciona
extensions/piagentui-server.tsé a extensão do Pi. Ela serve a UI compilada dedist/comhttp+wsdo Node e injetawindow.PI_BOOT_DATA(URL base e token).- Ao iniciar, escuta na porta
58785(ou na próxima livre) e grava a porta e um token aleatório em~/.pi/agent/piagentui-port.json. GET /global/healthé aberto; as outras rotas/api/*exigemAuthorization: Bearer <token>. O socket escuta em0.0.0.0, mas cada requisição é checada contra loopback, a menos que o acesso pela LAN em/api/network/accessesteja ligado (vem desligado).- O app Tauri lê o mesmo arquivo de descoberta pelo comando
get_pi_agent_connection, então o build desktop conecta no runtime local sem configuração manual. - Em containers, o router em Rust (
src-router/, axum) fica atrás do Caddy como gateway na frente dos serviços de frontend e backend.
Início rápido
| Ferramenta | Versão | Usada para |
|---|---|---|
| Node.js | >=22 (.tool-versions: 22.22.0) |
tudo |
| npm | a que vem com o Node | tudo (package-lock.json) |
| Rust | 1.85.0 (.tool-versions) |
app desktop e router do gateway |
| Docker Compose | recente | só a stack em containers |
| Pi Agent | instalado localmente | sessões e modelos reais |
git clone https://git.evandro.dev.br/evandro/PiAgentUI.git
cd PiAgentUI
npm ci # o postinstall roda scripts/copy-material-icons.mjs
npm run build # tsc -b && vite build -> dist/
npm run dev # servidor Vite em http://localhost:5173
npm run dev é só o front end: ele faz proxy de /api para 127.0.0.1:4096 sem o prefixo. Para o fluxo com o Pi, compile antes e deixe a extensão servir dist/ (o Pi carrega este repositório como pacote pelo campo pi.extensions do package.json):
npm run build
cat ~/.pi/agent/piagentui-port.json # {"port": 58785, "token": "..."}
# abra http://127.0.0.1:58785
Desktop e Android:
npm run tauri dev # janela desktop sobre o servidor Vite
npm run tauri build # bundles: nsis, dmg, deb (src-tauri/tauri.conf.json)
npm run tauri android dev # veja scripts/dev-android.sh
Antes de um PR, npm run validate roda typecheck, typecheck da extensão, lint, build e testes; é o gate que o CI roda em build.yml.
Configuração
A stack em containers foi herdada do deploy do OpenCodeUI. Copie .env.example para .env antes.
| Arquivo | Comando | O que faz |
|---|---|---|
docker-compose.yml |
docker compose up -d |
Stack completa: gateway (Caddy + router em Rust, 127.0.0.1:6658 e 6659), frontend, backend (opencode serve, 4096, limite de 4G de memória). |
docker-compose.standalone.yml |
docker compose -f docker-compose.standalone.yml up -d |
Só o front end, para um opencode serve já existente. Usa BACKEND_URL (padrão host.docker.internal:4096) e PORT (padrão 3000). |
docker-compose.host.yml |
docker compose -f docker-compose.yml -f docker-compose.host.yml up -d |
Override opcional: o backend roda privilegiado, com o socket do Docker e o / do host montado em /host. |
docker-compose.build.yml |
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build |
Override opcional: compila gateway, frontend e backend localmente a partir de docker/. |
Variáveis de ambiente (só para a stack em containers)
| Variável | Obrigatória | Descrição |
|---|---|---|
ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY, XAI_API_KEY |
Ao menos uma | Chaves de provedores de LLM repassadas ao container do backend. |
GATEWAY_PORT |
Não (6658) |
Porta do host para o ponto de entrada unificado. |
PREVIEW_PORT |
Não (6659) |
Porta do host para o ponto de entrada de previews. |
PREVIEW_DOMAIN |
Não | Domínio separado para previews; o proxy reverso encaminha para PREVIEW_PORT. |
WORKSPACE |
Não (./workspace) |
Pasta do host montada em /workspace no backend. |
OPENCODE_SERVER_PASSWORD |
Em deploys públicos | Senha do backend e do router. |
OPENCODE_SERVER_USERNAME |
Não (opencode) |
Usuário que acompanha a senha acima. |
PUBLIC_BASE_URL |
Não | URL base pública usada pelo router embutido no gateway. |
ROUTER_SCAN_INTERVAL |
Não (5) |
Intervalo de varredura do router. |
ROUTER_TOKEN_LENGTH |
Não (12) |
Tamanho dos tokens de rota gerados. |
ROUTER_PORT_RANGE |
Não (3000-9999) |
Faixa de portas que o router atende. |
ROUTER_EXCLUDE_PORTS |
Não (4096) |
Portas que o router ignora. |
DOCKER_API_VERSION |
Não (1.40) |
Versão da API do Docker para o backend; definida no docker-compose.yml, não no .env.example. |
USE_CHINA_MIRROR |
Não (1) |
Opção de build da imagem do backend: usa os mirrors abaixo. |
APT_MIRROR, APT_SECURITY_MIRROR, NPM_CONFIG_REGISTRY, NODEJS_ORG_MIRROR, PIP_INDEX_URL, PIP_TRUSTED_HOST |
Não | Mirrors para o toolchain do backend. |
MISE_INSTALL_URL, OPENCODE_INSTALL_URL |
Não | URLs de instalação usadas no build da imagem do backend. |
Estado do projeto
Beta, antes da 1.0 (0.6.10), mantido por um desenvolvedor. As releases saem do release.yml em tags v* (artefatos para Windows, macOS, Linux e Android); o deploy.yml publica o build web com VITE_BASE_PATH=/PiAgentUI/.
- O nome OpenCodeUI ainda não saiu de tudo: o crate do router em Rust é
opencodeui-router, as imagens sãoopencodeui-*, os APKs Android saem comoOpenCodeUI-*, os comentários do.env.exampleestão em chinês e o backend Docker rodaopencode serve, que é do deploy herdado, não do fluxo com a extensão do Pi. docker-compose.ymledocker-compose.standalone.ymlainda puxam a imagem upstreamghcr.io/lehhair/opencodeui-frontend.- Os testes são de componente e de servidor (Vitest). Não há testes do shell Tauri nem do router em Rust além da compilação, nem teste end-to-end no navegador, nem meta de cobertura.
- A entrada de voz depende de um endpoint de STT compatível com OpenAI e não tem teste automatizado no navegador.
Issues e pull requests vão para o issue tracker; rode npm run validate antes de abrir um PR.
Licença
GPL-3.0-only, veja LICENSE. O PiAgentUI é um fork retrabalhado do OpenCodeUI; o autor original está creditado em src-tauri/Cargo.toml.
