第五阶段:Web UI 与 MoM

对应源文件:

  • packages/web-ui/src/
  • packages/mom/src/

一、Web UI 概述

web-ui 是 pi 的浏览器端界面包。它使用 Lit 框架(Google 的 Web Components 库)构建,可以嵌入到任何 Web 应用中。

与 TUI 的关系

TUI 和 Web UI 是两套完全独立的 UI 实现,共享同一个 Agent 后端。

                    ┌── TUI(终端)   → packages/tui + coding-agent/modes/interactive/
Agent(agent 包)──┤
                    └── Web UI(浏览器)→ packages/web-ui

TUI 面向终端用户(开发者),Web UI 面向浏览器用户(可能是非技术用户或集成到 Web 应用中)。

架构

packages/web-ui/src/
├── ChatPanel.ts         # 顶层面板(聊天 + 工件面板)
├── index.ts             # 入口 + Agent 设置
├── components/          # UI 组件
│   ├── AgentInterface.ts  # 主聊天界面
│   ├── sandbox/           # 沙箱执行环境
│   └── ...
├── dialogs/             # 对话框组件
├── tools/               # 工具渲染器
│   └── artifacts/       # 工件系统(HTML/代码预览)
├── prompts/             # System prompt 模板
├── storage/             # 本地存储
└── utils/               # 工具函数

核心组件

ChatPanel -- 顶层布局组件

@customElement("pi-chat-panel")
class ChatPanel extends LitElement {
  @state() agent?: Agent;           // 绑定的 Agent
  @state() agentInterface?: AgentInterface;  // 聊天界面
  @state() artifactsPanel?: ArtifactsPanel;  // 工件面板
}

布局方式:

  • 宽屏(>800px):聊天面板 | 工件面板(各 50%)
  • 窄屏(≤800px):聊天面板全屏 + 工件面板 overlay

AgentInterface -- 聊天界面

负责:

  • 消息流式渲染
  • 输入框和附件
  • 模型/思考级别选择器
  • 主题切换

工件系统(Artifacts)

Web UI 有一个独特的"工件"(Artifacts)系统:AI 可以创建 HTML/CSS/JS 工件,在沙箱 iframe 中实时预览。

AI 调用 artifacts 工具 → 创建 HTML 代码
  ↓
ArtifactsPanel 接收工件
  ↓
在 sandbox iframe 中渲染(安全隔离)
  ↓
用户可以实时看到效果

沙箱通过 SandboxRuntimeProvider 提供文件系统:

  • ArtifactsRuntimeProvider:提供工件文件
  • AttachmentsRuntimeProvider:提供用户上传的附件

Proxy Stream

Web UI 不能直接调用 LLM API(API key 安全问题)。它通过 agent 包的 streamProxy() 函数,通过服务器代理调用:

Web UI → streamProxy() → POST /api/stream → 代理服务器 → LLM Provider
  ↑                                                           ↓
  └──────────────── SSE 事件流(无 partial 字段) ←──────────┘

二、MoM(Multi-agent Orchestrator for Messaging)

mom 是一个独立的包,实现了通过 Slack 运行 pi agent

做什么

Slack 消息 → MoM bot → 创建/复用 AgentRunner → 执行 pi agent → 回复到 Slack

它是 pi agent 能力在团队协作场景中的延伸。

架构

packages/mom/src/
├── main.ts          # 入口 + CLI
├── slack.ts         # Slack WebSocket API 集成
├── agent.ts         # Agent 运行器管理
├── store.ts         # 会话/状态持久化
├── events.ts        # 文件系统事件监听
├── sandbox.ts       # 沙箱配置(host/Docker)
├── context.ts       # Slack 上下文适配
├── download.ts      # 频道历史下载
└── log.ts           # 日志

核心流程

1. 启动时
   ├── 解析参数(working-dir, sandbox 配置)
   ├── 验证 Slack tokens
   ├── 启动 SlackBot(WebSocket 连接)
   └── 启动文件事件监听器

2. 收到 Slack 消息时
   ├── getState(channelId)        → 获取/创建频道状态
   ├── getOrCreateRunner(sandbox) → 获取/创建 Agent 运行器
   ├── createSlackContext(event)  → 适配 Slack 上下文
   ├── runner.run(ctx, store)     → 运行 agent
   └── 通过 ctx.respond() 回复到 Slack

3. 收到 "stop" 命令时
   ├── state.runner.abort()       → 取消当前运行
   └── 回复 "_Stopping..._"

沙箱执行

MoM 支持两种执行模式:

模式说明
host直接在宿主机上运行(开发用)
docker:<name>在 Docker 容器中运行(生产安全)

Docker 模式通过 SSH 连接到容器,把 bash/read/write 操作委托到容器内执行。

事件系统

MoM 监听工作目录下的 .events/ 文件夹。当外部系统(CI/CD、GitHub Webhooks 等)把事件文件放到这个目录时,MoM 自动读取并处理:

.events/
├── github-pr-opened.md     → MoM 读取 → 发送给 agent 处理
├── ci-failed.md            → MoM 读取 → 发送给 agent 处理
└── ...

这使得 MoM 不仅仅是一个聊天 bot,还是一个事件驱动的自动化平台


小结

Web UI
├── 技术栈:Lit Web Components
├── 核心:ChatPanel + AgentInterface
├── 特色:Artifacts 系统(sandbox iframe 预览)
├── 通信:通过 streamProxy() 代理 LLM 调用
└── 布局:响应式(宽屏分栏 / 窄屏全屏)

MoM
├── 功能:Slack bot 运行 pi agent
├── 沙箱:host 或 Docker 隔离执行
├── 事件:文件系统事件驱动(.events/ 目录)
├── 多频道:每个 Slack 频道独立的 agent 状态
└── 集成:CI/CD、GitHub Webhooks → 自动处理