# 第五阶段：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** -- 顶层布局组件

```typescript
@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 → 自动处理
```
