> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veadk.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# VeADK Frontend

VeADK 自带一个生产级 React 前端——一个面向企业的智能体应用工作台，通过 Google ADK API Server 与智能体通信：在界面中创建、调试、管理智能体，并将其接入使用。`veadk frontend` 是一个自包含的启动器：在默认模式下，它以单个进程同时提供这套 React 界面与智能体 API，两者同源，因此无需单独部署后端，也无需处理跨域配置。

## 功能一览

* **创建智能体**：当前可通过自定义配置创建智能体，产出可运行的 VeADK 项目（`agent.py`、`requirements.txt` 等），并可在线预览、编辑与下载。其他创建方式及其可用范围见 [Studio](/productions/veadk/preview/zh/components/frontend/studio)。
* **多模态消息**：上传图片、TXT、Markdown、PDF 和视频；用户附件与模型返回的媒体均可预览并随历史会话重新加载。
* **对话与调试**：与智能体多轮对话，展示思考过程、工具调用、子智能体移交、Token 与用时；对话支持渲染 ECharts 与 Mermaid 图表（含源码切换和放大查看）、图片放大、视频与音频播放、文件预览和长时任务进度；内置工具（网页搜索、图像生成、视频生成、长期记忆检索、知识库检索）在执行时显示专属图标与运行状态；对话中还会渲染智能体返回的 [A2UI](/productions/veadk/preview/zh/components/frontend/a2ui) 富界面卡片。
* **停止生成**：智能体回复过程中，输入框的发送按钮变为停止按钮，点击后中断当前回复。已接收的内容保留在对话中，停止后可立即在同一会话中发送下一条消息。该能力在 `veadk frontend` 与 `veadk studio` 的对话页面（含沙箱会话）均生效。
* **上下文用量指示器**：输入框发送按钮旁显示当前模型的上下文窗口用量。悬停或聚焦时展开 100 格用量构成图，将上下文占用分为系统与工具（估算）、输入与历史、输出与思考、剩余容量四部分。系统与工具占用为估算值，因为模型使用量统计未单独报告该部分。上下文窗口大小按云服务商和模型名称确定。该能力在 `veadk frontend` 与 `veadk studio` 的智能体对话页面均生效。
* **智能体选择器**：左上角切换智能体；悬停可查看该智能体的模型与挂载的工具。
* **智能体信息栏**：发送第一条消息后，对话右侧工作区展示当前智能体的描述、模型、工具、技能以及可选的多智能体协作拓扑；屏幕较窄时改为从标题栏按钮打开的抽屉，避免遮挡对话内容。
* **技能与子智能体**：输入 `/` 选择当前智能体挂载的技能，输入 `@` 把本轮任务交给可选的子智能体。
* **技能中心**：从 Skill Hub、本地上传或 AgentKit SkillSpace 选择技能，供创建智能体时使用。
* **历史会话**：自动保存、按时间排序，可重新打开或删除。
* **智能搜索**：「会话」源检索当前智能体的历史消息；「网页」源调用已挂载的联网搜索工具；「知识库」与「长期记忆」源通过智能体已配置的后端执行语义检索。界面根据智能体实际挂载的能力启用来源，并在结果中标注索引或来源名称及后端类型。
* **消息反馈回流**：连接云端 AgentKit Runtime 时，回答下方的赞/踩按钮会将当前问题、回答和反馈状态写入 AgentKit 评测集。每个智能体自动维护 `{agent_name}_good_case` 与 `{agent_name}_bad_case` 两个评测集，切换或取消反馈会幂等更新对应样本。反馈按 Runtime 实际的 app 名称关联评测集，并在首选地域查询失败时自动回退到另一个地域。赞/踩按钮旁提供「查看评测案例」入口，可直接跳转到该智能体的评测案例列表并预览当前消息对应的样本。如果标准名称已被云端占用但不可见，Studio 会改用带稳定短后缀的备用名称并在后续反馈中复用；Runtime 不支持 Session 状态更新时，浏览器会保留兼容性缓存。
* **添加 AgentKit 智能体**：填入访问地址与 API Key，按 ADK 协议接入远程智能体，接入后出现在选择器中。
* **Studio 部署**：在同一工作台中检查生成代码，配置地域、消息渠道、网络与环境变量，然后部署到 AgentKit 并查看任务状态。
* **导出会话**：每条助手回复旁可将截至该轮的全部输入与输出导出为 PNG 图片或 PDF 文件，支持下载或复制到剪贴板（复制仅在 PNG 格式下可用）。该能力在 `veadk frontend` 与 `veadk studio` 的对话页面均生效。
* **Tracing 观测**：查看本次会话的调用火焰图。
* **登录**：支持 SSO 或本地用户名。

## 完成工具 OAuth 授权

当 MCP 或其他工具需要 OAuth 凭证时，Frontend 会在对话中显示授权卡片。选择授权后，浏览器会打开身份提供方页面；授权回调返回 Frontend 后，当前工具调用会自动继续，无需重新发送消息。若回调无法由当前页面自动读取，界面会要求粘贴完整的回调 URL。

身份提供方中登记的回调 URL 必须与工具配置一致，并指向当前 Frontend 可访问的地址。浏览器阻止授权窗口时，应允许本站打开弹窗后重试。

## 运行

先完成[安装](/productions/veadk/preview/zh/get-started/installation)与[模型配置](/productions/veadk/preview/zh/components/agent/model)。发行包已带界面，无需先安装 Node.js 或构建前端。准备一个包含 `agent.py` 和 `__init__.py` 的智能体目录，并在 `agent.py` 中暴露 `root_agent`；完整目录示例见 [A2UI](/productions/veadk/preview/zh/components/frontend/a2ui#项目准备)

```bash theme={null}
veadk frontend --dev --agents-dir ./agents --open
```

浏览器打开 `http://127.0.0.1:8000` 后，选择本地智能体并发送文本，确认收到回复。只传 `--agents-dir` 不会切换到本地列表，必须同时使用 `--dev`。连接云端 Runtime 时省略 `--dev`，并按当前云服务商配置 AK/SK

<Warning>
  更改监听地址使其他设备可访问前，先配置 SSO 或受信任的网关。`gateway` 模式依赖网关完成验证，应阻止请求绕过网关直接访问服务
</Warning>

### 开发模式（热更新）

只有修改前端源码时才需要此模式。在 VeADK 源码根目录启动后端；另开终端进入 `frontend` 目录启动 Vite。生产构建执行 `npm run build`，再用 `--frontend-dir` 指向构建产物

开发模式下 `veadk frontend` 只提供智能体 API，并为 Vite 开发服务器（`http://localhost:5173`，回退到 `http://localhost:5174`）放行 CORS；界面则由 Vite 单独以热更新方式运行。

```bash lines theme={null}
veadk frontend --dev --vite --agents-dir ./agents   # 仅 API，为 Vite 放行 CORS
cd frontend
npm install
npm run dev                    # http://localhost:5173，代理 API
```

### 组件预览

`frontend` 目录包含一个独立的组件预览页面，用于浏览共享组件库中的组件实现。预览页面不依赖后端服务，按 Foundation、Base、Block、AI App、Node、Layout 分组展示，组内按组件名称排序；Foundation 下包含前端开发规范页面和设计 Token，每个组件页面提供本页目录，支持通过 `#组件/小节` 链接跳转到变种子节和参数区。预览页面还提供明暗主题切换和从 TypeScript 接口生成的参数表。此入口独立于 Studio 生产构建，不替换现有业务页面。

```bash lines theme={null}
cd frontend
npm install
npm run dev:components
# 打开 http://127.0.0.1:5186/components-preview/
```

## `veadk frontend` 命令

| 选项 | 默认值 | 说明 |
| :- | :- | :- |
| `--agents-dir` | `.` | 智能体应用目录，每个子目录暴露一个 `root_agent`。 |
| `--frontend-dir` | 包内置构建产物，回退至 `./frontend/dist` | 覆盖已构建 React 界面所在目录。优先使用显式传入的目录，其次为包内置界面，最后回退至相对当前目录的 `./frontend/dist`。 |
| `--host` | `127.0.0.1` | 监听地址。 |
| `--port` | `8000` | 监听端口。 |
| `--provider` | `volcengine` \| `byteplus` | 云服务商。未指定时依次读取 `AGENTKIT_CLOUD_PROVIDER` 与 `CLOUD_PROVIDER` 环境变量，均未设置时使用 `volcengine`；选择 `byteplus` 时使用 `BYTEPLUS_ACCESS_KEY`、`BYTEPLUS_SECRET_KEY` 和可选的 `BYTEPLUS_SESSION_TOKEN` 提供凭证，Runtime 列表默认地域为 `BYTEPLUS_REGION` 或 `ap-southeast-1`。 |
| `--dev` | 关闭 | 在智能体选择器中加载本地智能体，而不是云端 AgentKit Runtime。 |
| `--vite` | 关闭 | 仅提供 API，并允许 Vite 开发服务器跨域访问；用于开发 React 前端。 |
| `--oauth2-user-pool` | — | VeIdentity 用户池名称。与客户端同时设置后启用 SSO。 |
| `--oauth2-user-pool-client` | — | VeIdentity 用户池客户端名称。 |
| `--oauth2-user-pool-uid` | 环境变量 `OAUTH2_USER_POOL_ID` | 用 UID 代替名称指定用户池。 |
| `--oauth2-user-pool-client-uid` | 环境变量 `OAUTH2_USER_POOL_CLIENT_ID` | 用 UID 代替名称指定客户端。 |
| `--oauth2-redirect-uri` | `http://{host}:{port}/oauth2/callback` | OAuth2 回调地址，环境变量 `OAUTH2_REDIRECT_URI`。部署到公网或 runtime 时需设置。 |
| `--oauth2-provider` | `veidentity`（配置了用户池时） | SSO provider 标识，环境变量 `OAUTH2_PROVIDER`。可取 `veidentity`、`github`、`google` 或自定义名称。 |
| `--oauth2-provider-label` | provider 内置文案 | 登录按钮的显示文案，环境变量 `OAUTH2_PROVIDER_LABEL`。 |
| `--auth-mode` | `frontend` | `frontend` 由本服务处理 OAuth2；`gateway` 信任上游网关验证并转发的 JWT。 |
| `--generated-agent-test-run-ttl` | `1800` | Studio 生成智能体的临时调试进程保留秒数。 |
| `--open / --no-open` | `--no-open` | 服务启动后是否打开系统浏览器；`--vite` 模式下忽略。 |
| `--site-title` | `VEADK_SITE_TITLE` | 系统名称，最多 16 个字符 |
| `--site-logo` | `VEADK_SITE_LOGO` | 本地图片或 HTTP(S) Logo 地址 |
| `--sandbox-chat-codex-tool-id` | `SANDBOX_CHAT_CODEX` | 临时会话使用的 CodeEnv Tool ID |
| `--sandbox-chat-openclaw-tool-id` | `SANDBOX_CHAT_OPENCLAW` | OpenClaw 会话的 ArkClawEnv Tool ID |
| `--sandbox-chat-hermes-tool-id` | `SANDBOX_CHAT_HERMES` | Hermes 会话的 HermesEnv Tool ID |
| `--sandbox-chat-codex-snapshot-tool-id` | `SANDBOX_CHAT_CODEX_SNAPSHOT` | 持久化会话的 CodeEnv Tool ID |
| `--sandbox-chat-openclaw-snapshot-tool-id` | `SANDBOX_CHAT_OPENCLAW_SNAPSHOT` | 持久化 OpenClaw 会话的 Tool ID |
| `--sandbox-chat-hermes-snapshot-tool-id` | `SANDBOX_CHAT_HERMES_SNAPSHOT` | 持久化 Hermes 会话的 Tool ID |
| `--super-admin` | `VEADK_STUDIO_SUPER_ADMIN` | 初始化 Identity 角色的超级管理员邮箱或 UID |
| `--admin` | `VEADK_STUDIO_ADMINS` | 本地管理员名单；配置条件见 Studio 角色说明 |
| `--developer` | `VEADK_STUDIO_DEVELOPERS` | 本地开发者名单；配置条件见 Studio 角色说明 |
| `--help` | — | 查看当前安装版本的命令帮助 |

<Note>
  非开发模式下，若未找到已构建的界面目录，命令会报错并提示先执行 `npm run build`。开发 React 前端时使用 `--vite`，并可同时使用 `--dev` 加载本地智能体。
</Note>

## 多模态附件与存储

输入框支持 PNG、JPEG、WebP、GIF、TXT、Markdown、PDF、MP4、WebM 和 QuickTime，默认单文件上限为 20 MB。PDF 会在模型调用前渲染为逐页图片；相关依赖从 1.0.5 起默认安装。

附件正文与 ADK Session 分开保存，Session Event 仅记录稳定引用。默认写入本地临时目录；需要跨进程保留时可改用 TOS：

| 环境变量 | 默认值 | 说明 |
| - | - | - |
| `VEADK_MEDIA_STORAGE` | `local` | `local` 或 `tos`。 |
| `VEADK_MEDIA_LOCAL_DIR` | `/tmp/veadk-media` | 本地媒体根目录。 |
| `VEADK_MEDIA_MAX_FILE_BYTES` | `20971520` | 单文件与模型输出的字节上限。 |
| `VEADK_MEDIA_TOS_PREFIX` | `veadk-media` | TOS 对象 Key 前缀。 |
| `DATABASE_TOS_BUCKET` | — | TOS Bucket，使用 `tos` 时必填。 |
| `DATABASE_TOS_REGION` | 按云环境推导 | TOS 地域。 |

```bash lines theme={null}
export VEADK_MEDIA_STORAGE=tos
export DATABASE_TOS_BUCKET="your-bucket"
export DATABASE_TOS_REGION=cn-beijing
export VOLCENGINE_ACCESS_KEY="your-access-key"
export VOLCENGINE_SECRET_KEY="your-secret-key"
veadk frontend --agents-dir examples
```

<Warning>
  本地模式使用 `/tmp`，文件可能随进程或宿主机回收而丢失。需要长期保存附件时应使用 TOS，并按用户权限限制 Bucket 访问。
</Warning>

## 使用技能与子智能体

在输入框中输入 `/` 可搜索当前智能体挂载的技能，输入 `@` 可选择允许转移的子智能体。选中项以可移除的标签显示，不会作为普通文本发送。选择子智能体后，技能列表会切换为目标智能体自身挂载的技能。

## 使用 Studio 部署

`veadk studio` 启动专注于创建与管理智能体的界面。准备部署时，在项目预览中检查生成代码并配置地域、消息渠道、网络与环境变量，然后由 Studio 创建 AgentKit Runtime。

```bash lines theme={null}
veadk studio --host 127.0.0.1 --port 8000
```

`veadk studio deploy` 可把 Studio 本身部署到 VeFaaS。未指定 `--iam-role` 时，命令会创建或复用默认服务角色，并附加 Studio 查询模型、日志、追踪、知识库、记忆与身份资源所需的只读权限。传入自定义角色时，命令不会修改其策略。

## 认证

会话与记忆按 ADK 的 `user_id` 隔离，该 `user_id` 来自登录用户。命令启动时会先加载当前目录及其上层目录中的 `.env` 文件，因此下述环境变量可写入 `.env`。

**SSO** —— 传入用户池与客户端后启用。前端会展示登录页并跳转到身份提供方，登录后用户信息接口返回的用户标识将作为 `user_id`。用户池与客户端既可用名称指定，也可用 UID 指定。

```bash lines theme={null}
veadk frontend --agents-dir examples \
  --oauth2-user-pool "your-user-pool-name" \
  --oauth2-user-pool-client "your-user-pool-client-name"
# 或用 UID，读环境变量 OAUTH2_USER_POOL_ID / OAUTH2_USER_POOL_CLIENT_ID
# --oauth2-user-pool-uid <id> --oauth2-user-pool-client-uid <id>
```

启用 VeIdentity SSO 需要进程能拿到火山引擎凭证。中间件保护 API，同时放行界面外壳、`/web/auth-config`、`/favicon.ico`、`/assets` 与 `/skillhub`，因此应用能加载并展示自己的登录页，而不是被直接重定向到身份提供方。登录按钮的文案与图标由配置驱动。

**第三方 / 自定义 OAuth2（环境变量）** —— 不依赖 VeIdentity 用户池时，只要设置 `OAUTH2_CLIENT_ID`（及密钥），即可接入 GitHub、Google 或任意 OIDC 登录。端点来源按以下顺序确定：内置预设（`OAUTH2_PROVIDER=github` 或 `google`）、OIDC 自动发现（设置 `OAUTH2_ISSUER`）、显式端点（`OAUTH2_AUTHORIZE_URL` 等）。

| 环境变量 | 说明 |
| :- | :- |
| `OAUTH2_PROVIDER` | provider 标识：`github`、`google` 或自定义名称。决定登录按钮文案与内置预设。 |
| `OAUTH2_CLIENT_ID` / `OAUTH2_CLIENT_SECRET` | OAuth2 客户端凭据。设置 `OAUTH2_CLIENT_ID` 即启用通用 provider。 |
| `OAUTH2_ISSUER` | OIDC issuer 基址，端点将自动发现，例如 `https://accounts.google.com`。 |
| `OAUTH2_AUTHORIZE_URL` / `OAUTH2_TOKEN_URL` / `OAUTH2_USERINFO_URL` | 显式端点，用于非 OIDC provider。 |
| `OAUTH2_SCOPE` | 覆盖请求的 scope。 |
| `OAUTH2_PROVIDER_LABEL` | 覆盖登录按钮文案。 |
| `OAUTH2_REDIRECT_URI` | 回调地址。部署到公网或 runtime 时设为公网回调，并在 OAuth 应用中登记同一地址；本地默认 `http://{host}:{port}/oauth2/callback`。 |

GitHub 预设仅需客户端凭据：

```bash lines theme={null}
export OAUTH2_PROVIDER=github
export OAUTH2_CLIENT_ID="your-github-oauth-client-id"
export OAUTH2_CLIENT_SECRET="your-github-oauth-client-secret"
export OAUTH2_REDIRECT_URI=http://127.0.0.1:8000/oauth2/callback
veadk frontend --agents-dir examples
```

Google 同理，把 `OAUTH2_PROVIDER` 换成 `google`；Keycloak、Auth0、Okta 等任意 OIDC 则设置 `OAUTH2_ISSUER` 加客户端凭据即可。完整示例见仓库 `examples/front_with_sso/`。

连接使用 `custom_jwt` 鉴权的 AgentKit Runtime 时，服务端会转发当前会话已验证的 OAuth access token。Token 的 issuer 必须匹配 Runtime 的 discovery URL，客户端 ID 也必须包含在 Runtime 的 `allowed_clients` 中。

<Warning>
  部署到 runtime 或公网时，OAuth 回调必须指向外部可访问的地址：把 `OAUTH2_REDIRECT_URI` 设为公网回调 URL，并在 OAuth 应用里登记同一地址。Cookie 的 `Secure` 标志会根据该地址是否为 HTTPS 自动开启。
</Warning>

**无 SSO（本地用户名）** —— 不传上述参数时，登录页会让用户输入一个用户名（字母加数字，不超过 16 位），保存在本地并作为 `user_id`。此时服务始终返回未认证状态与空的 provider 列表，应用即展示本地用户名登录界面。

<Note>
  登录态会被缓存：SSO 走 `veadk_session` Cookie，本地模式走 `localStorage`。会话本身在发送第一条消息或上传第一个附件时创建，而非打开页面时。发送首条消息后，对话页面会立即渲染该消息，服务端会话在后台创建期间会话 ID 显示为「初始化中」。退出登录为本地登出，即清除会话并回到登录页。
</Note>

<Note>
  启用 SSO 时，若登录态在使用过程中过期，界面会弹出「登录状态已过期」对话框。点击「重新登录」会在独立弹出窗口中打开登录页，当前编辑内容会保留；登录完成后，触发该提示的操作会自动重试并继续。弹出窗口与编辑页相互隔离，不会获得对编辑页的访问权限。该行为对 `veadk frontend` 与 `veadk studio` 均生效。
</Note>

## 前端服务安全限制

VeADK Frontend 可能部署到公网，因此会限制用户可控制的地址和文件路径：

* 调试运行会执行生成的项目；仅测试可信内容，并按 Studio 的测试范围限制模型地址和外部资源。
* 远程 AgentKit 代理要求提供 API Key，并只接受 HTTPS 的 `volceapi.com` 域名。
* AgentKit 部署文件必须位于本次项目目录内，绝对路径和跳出目录的相对路径会被拒绝。
* 静态文件只允许从已构建的界面目录读取，不能通过路径跳转读取主机上的其他文件。

这些限制不会代替身份认证。公网部署仍应启用 SSO 或受信任的上游网关，并按最小权限原则配置云资源凭证。只需要创建和管理能力时，可以使用[Studio 智能体工作台](/productions/veadk/preview/zh/components/frontend/studio)。

## 渲染流程

前端与 Google ADK API Server 通信：列出可用智能体、创建会话，并以流式方式实时接收智能体的输出。当智能体返回 A2UI 消息时，前端从中解析出界面指令，据此创建并增量更新对应的界面区域，再按每个组件的类型渲染出相应的 React 组件。组件类型到渲染器的映射由一张注册表维护，因此新增一种组件类型，只需为它注册对应的渲染器。

## 添加企业自定义组件

一个自定义组件由两个部分组成，它们共享同一个 catalog id。后端部分见 [A2UI](/productions/veadk/preview/zh/components/frontend/a2ui#自定义组件)；前端部分如下。

**前端部分** —— 新建一个目录即可自动注册，无需修改任何中心文件：

```text lines theme={null}
src/a2ui/components/RevenueChart/
├── RevenueChart.tsx
└── index.ts
```

```ts title="src/a2ui/components/RevenueChart/index.ts" lines theme={null}
import { register } from "../../registry";
import { RevenueChart } from "./RevenueChart";
register("RevenueChart", RevenueChart);
```

```tsx title="src/a2ui/components/RevenueChart/RevenueChart.tsx" lines theme={null}
import type { ComponentRendererProps } from "../../registry";

export function RevenueChart({ node, ctx }: ComponentRendererProps) {
  const values = ctx.resolve(node.series);
  const series = Array.isArray(values) ? values.filter(
    (value): value is number => typeof value === "number"
  ) : [];
  return <ol>{series.map((value, index) => (
    <li key={index}>{value.toLocaleString()}</li>
  ))}</ol>;
}
```

新增的组件目录会被自动发现并注册，无需改动任何中心配置文件。

<Note>
  未注册渲染器的未知组件会回退到可折叠的 JSON 视图，因此目录与渲染器不匹配也不会导致界面崩溃。
</Note>
