# chat-ui **Repository Path**: cdevel/chat-ui ## Basic Information - **Project Name**: chat-ui - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-31 - **Last Updated**: 2026-05-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 商图助手 Chat UI 基于 Vite、React 19 和 TypeScript 的三栏 AI 电商聊天界面。对话区保持简洁,结构化结果集中沉淀到右侧工作区,交互设计参考了 Claude Artifacts、ChatGPT Canvas 和 Cursor Composer 的任务感知模式。 ## 核心特性 - 三栏布局:平台与场景导航、聊天主面板、结构化工作区 - 流式对话:支持 token 级输出和技能进度状态展示 - 结构化解析:从助手消息中提取步骤、选项、调研摘要、工作区卡片、表格和动作 - 会话持久化:聊天记录保存在本地,刷新后自动恢复 - 双层测试:Vitest 单元/组件测试 + Playwright mock E2E / 真实 API smoke ## 环境变量 参考 `.env.example` 创建本地环境文件: - `VITE_API_KEY`:浏览器直连时使用的网关鉴权 token,仅保留在本地环境中 - `VITE_MODEL`:默认模型名,当前默认 `hermes-agent` - `AGENT_SERVER_TARGET`:agent server 地址,Vite 开发代理和分发 console server 都会使用它 - `AGENT_SERVER_API_KEY`:分发 console server 代发给 agent server 的 Bearer token,可选 - `CONSOLE_HOST` / `CONSOLE_PORT`:开发态 console 的监听地址 - `CONSOLE_PREVIEW_HOST` / `CONSOLE_PREVIEW_PORT`:`npm run preview` 的监听地址 - `VITE_PREVIEW_BASE` / `PREVIEW_BASE`:预览链接识别用的主机名或 `host:port`,默认回退到当前 console 地址 ## 开发命令 - `npm run dev`:启动开发 console,自动按 `AGENT_SERVER_TARGET` 代理 `/api` - `npm run build`:执行 TypeScript 构建并产出生产包 - `npm run lint`:运行 ESLint - `npm run preview`:用 Vite 本地预览生产构建 - `npm run serve:dist`:启动分发用 console server,服务 `dist/` 并代理 `/api` - `npm run start:dist`:先构建再启动分发用 console server - `npm run mock:agent`:启动本地 mock upstream,供 `verify:console` / `verify:docker` 或代理联调使用 - `npm run verify:console`:对已启动的 console 做 `/health`、`/runtime-config.js` 和 `/api` smoke 校验 - `npm run verify:docker`:在 Docker 环境里自动完成 build、run、smoke 和容器清理 ## Docker 分发 仓库现在自带 [Dockerfile](Dockerfile) 和 [compose.yaml](compose.yaml),可以把现有分发 console 直接包装成容器。 ### Docker build / run ```bash docker build -t chat-ui . docker run --rm \ -p 4317:4317 \ -e CONSOLE_HOST=0.0.0.0 \ -e CONSOLE_PORT=4317 \ -e AGENT_SERVER_TARGET=http://host.docker.internal:8081 \ -e AGENT_SERVER_API_KEY=replace-with-api-key \ --add-host host.docker.internal:host-gateway \ chat-ui ``` ### Docker Compose ```bash AGENT_SERVER_TARGET=http://host.docker.internal:8081 docker compose up --build CONSOLE_BASE_URL=http://127.0.0.1:4317 npm run verify:console ``` ### 一键 Docker 验证 ```bash AGENT_SERVER_TARGET=http://host.docker.internal:8081 npm run verify:docker ``` 如果需要在本地先用稳定假上游验证完整链路,可以先开一个 mock upstream: ```bash npm run mock:agent AGENT_SERVER_TARGET=http://host.docker.internal:8088 VERIFY_API_BODY_INCLUDES='"ok":true' npm run verify:docker ``` 说明: - 容器内 console 固定监听 `0.0.0.0`,对外端口由 `CONSOLE_PORT` 控制。 - `AGENT_SERVER_TARGET` 继续决定 `/api` 最终代理到哪个 agent server。 - 若 agent server 在宿主机上,Linux 下通过 `host.docker.internal:host-gateway` 暴露宿主地址。 - `npm run verify:docker` 会自动执行 Docker build、启动临时容器、等待 `/health` 就绪、运行 `npm run verify:console` 等价校验并在结束后清理容器。 - 如需保留容器排障,可设置 `VERIFY_DOCKER_KEEP_CONTAINER=1`。 - 仓库已新增 [ci.yml](.github/workflows/ci.yml),会在 Ubuntu runner 上自动执行单测、lint、build、mock E2E 和 Docker smoke。 ## 启动与分发 ### 本地开发 1. 在 `.env.local` 里设置 `AGENT_SERVER_TARGET=http://你的-agent-ip:端口` 2. 如需让 console 绑定到指定地址,设置 `CONSOLE_HOST` 和 `CONSOLE_PORT` 3. 执行 `npm run dev` ### 分发态 console 1. 执行 `npm run build` 2. 设置 `AGENT_SERVER_TARGET` 为目标 agent server 地址 3. 如需 server 端代注入 token,再设置 `AGENT_SERVER_API_KEY` 4. 设置 `CONSOLE_HOST` / `CONSOLE_PORT` 为 console 对外监听地址 5. 执行 `npm run serve:dist` 分发 server 会完成两件事: - 服务 `dist/` 下的静态资源 - 把浏览器发往 `/api/*` 的请求转发到 `AGENT_SERVER_TARGET` - Docker 分发时复用同一套 `serve:dist` 逻辑,不新增第二套代理层 当前 `serve:dist` 还带有以下默认护栏: - 所有响应默认附带 `X-Content-Type-Options: nosniff`、`X-Frame-Options: DENY` 和 `Referrer-Policy: same-origin` - `/runtime-config.js` 使用 `Cache-Control: no-store`,避免分发态预览地址被旧配置缓存 - `index.html` 与前端路由回退响应使用 `Cache-Control: no-cache`,静态资源默认使用 `public, max-age=3600` - `/api` 代理默认有 `15s` 上游超时,超时返回 `504`,上游不可达返回 `502` ### 分发 smoke 命令 对已经启动的本地 `serve:dist` 或 Docker 容器,可以直接运行: ```bash npm run verify:console ``` 默认会校验: - `/health` 返回 `status: ok` - `/runtime-config.js` 包含运行时配置注入标记 - `/api/ping` 返回 `200` 常用环境变量: - `CONSOLE_BASE_URL`:待校验的 console 地址,默认 `http://127.0.0.1:${CONSOLE_PORT:-4317}` - `VERIFY_API_STATUS`:期望的 `/api` 状态码;可用于 Docker 环境里显式验证 `502` 或 `504` - `VERIFY_API_BODY_INCLUDES`:要求 `/api` 响应体包含的关键字 - `VERIFY_RUNTIME_BODY_INCLUDES`:要求 `/runtime-config.js` 包含的关键字,例如预期 `previewBase` - `VERIFY_API_PING=0`:跳过 `/api` 检查,仅验证静态分发面 `npm run verify:docker` 额外支持: - `VERIFY_DOCKER_IMAGE`:自定义临时镜像 tag,默认 `chat-ui:verify-local` - `VERIFY_DOCKER_HOST_PORT`:映射到本机的验证端口,默认跟随 `CONSOLE_PORT` - `VERIFY_DOCKER_CONTAINER`:自定义临时容器名 - `VERIFY_DOCKER_STARTUP_TIMEOUT_MS`:容器启动等待时间,默认 `20000` - `VERIFY_DOCKER_POLL_INTERVAL_MS`:健康检查轮询间隔,默认 `500` - `VERIFY_DOCKER_KEEP_CONTAINER=1`:失败或成功后保留容器,便于继续看日志 ## 测试命令 - `npm run test`:运行全部 Vitest 单元/组件测试 - `npm run test:unit`:同上,保留为显式单测入口 - `npm run test:watch`:Vitest watch 模式 - `npm run test:coverage`:输出覆盖率报告 - `npm run test:e2e`:运行 Playwright mock 回归套件 - `npm run test:e2e:real`:运行真实 API smoke,用本地环境和现有 8081 服务验证最小链路 - `npm run test:unit -- scripts/dockerfile.test.mjs`:只跑 Dockerfile 运行期载荷回归测试 - `npm run test:unit -- scripts/mock-agent-server.test.mjs`:只跑 mock upstream server 的 node 测试 - `npm run test:unit -- scripts/serve-console.test.mjs`:只跑分发 console 的 node 契约测试 - `npm run test:unit -- scripts/verify-console.test.mjs`:只跑分发 smoke CLI 的 node 测试 - `npm run test:unit -- scripts/verify-docker.test.mjs`:只跑 Docker 编排脚本的 node 测试 ## 测试策略 ### 单元与组件测试 覆盖以下关键边界: - `src/lib/agentParser.ts`:步骤、选项、预览链接、调研 JSON 提取 - `src/lib/tagParser.ts`:工作区协议、动作、引导文案、场景注册 - `src/api/chat.ts`:SSE 流式解析、工具进度、Abort、HTTP error - `src/hooks/useSessions.ts`:localStorage 损坏恢复、写入节流、新建会话 - `src/components/chat/*` 与 `src/components/layout/ChatPanel.tsx`:输入、进度、单选/多选和工作区联动 ### Playwright mock E2E 默认走 mock SSE 响应,保证 CI 或本地回归稳定,当前覆盖: - 平台切换后消息上下文是否携带正确平台前缀 - 流式消息是否正确落到聊天区和工作区 - 工作区动作回传是否能触发第二轮请求 - 刷新后会话与工作区是否恢复 ### 真实 API smoke 真实 smoke 不依赖模型输出的具体文案,而是验证: - `/v1/models` 模型列表可访问 - 非流式 `/v1/chat/completions` 能返回正文 - 前端 UI 能发起流式会话并正常停止 ## 设计说明 - 对话区优先保留摘要、问题与下一步动作,避免原始工作区标签污染阅读体验 - 工作区承担结构化结果,包含卡片、评分、表格和动作按钮 - 空态和任务态保持明确分层,让用户知道当前是在“等待结构化结果”还是“执行中” ## 当前验证结果 - `npm run lint` 通过 - `npm run build` 通过 - `npm run test:unit` 通过 - `npm run test:e2e -- e2e/chat-ui.spec.ts` 通过 - `npm run test:e2e:real` 通过 - `npm run test:unit -- scripts/serve-console.test.mjs` 通过 - `npm run test:unit -- scripts/verify-console.test.mjs` 通过 - `CONSOLE_BASE_URL=http://127.0.0.1:4321 npm run verify:console` 通过 - `npm run test:unit -- scripts/dockerfile.test.mjs` 通过 - `npm run test:unit -- scripts/verify-docker.test.mjs` 通过 - `npm run test:unit -- scripts/mock-agent-server.test.mjs` 通过