2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00
2026-03-20 07:33:46 +00:00

vibe-next-template

Nova Agent 示例模板工程。Nova 是一个创建 Agent 的 SaaS 产品,可以通过 Nova 创建能够操作沙箱、浏览器、文件系统的专业 Agent。本项目基于 Next.js 提供完整的 Agent 聊天前端,包含消息流、事件列表、会话管理与文件上传能力。

项目中 .nova/config.json 内置了一个示例 Agent如需基于本模板开发自己的应用请在 Nova 平台创建 Agent 并替换配置。

技术栈

  • Next.js 16App Router / React 19 / TypeScript 5
  • Tailwind CSS 4 / Radix UI / Lucide React Icons
  • Zustand状态管理
  • 自定义 WebSocket 客户端(实时通信)
  • 自定义 HTTPClientFetch 封装,支持拦截器)
  • Drizzle ORM + PostgreSQL
  • Winston日志生产环境按天轮转
  • Shiki代码高亮/ React Markdown + Remark GFM

快速开始

  1. 安装依赖:pnpm install
  2. .env环境变量文件已经初始化完成了,所以设计环境变量的需要在这里修改
  3. (可选)修改 .nova/config.json,替换为你自己的 Agent
  4. 启动开发服务器:pnpm dev(端口 13000

Agent 配置

Agent 配置存放在 .nova/config.json

{
  "agents": [
    {
      "agent_id": "70da765f2d42490ca574d72dce4d24fe",
      "agent_name": "Nova示例Agent",
      "agent_description": "一个Nova的Agent示例包含Agent具备的通用功能文件操作、沙箱环境执行、浏览器操作等等。"
    }
  ]
}
  • agents 数组中的第一个 Agent 作为默认使用的 Agent
  • 在 Nova 平台创建新 Agent 后,将 agent_idagent_nameagent_description 替换为新 Agent 的信息
  • 配置通过 app/api/nova-config.tsgetDefaultAgentId() 在服务端读取,启动后缓存

目录结构

.nova/
  config.json             # Agent 配置agent_id, agent_name, agent_description

app/
  layout.tsx              # 根布局Geist Sans/Mono 字体)
  page.tsx                # 主入口,初始化聊天连接
  globals.css             # 全局样式
  api/                    # Next.js API 路由BFF 层,代理 Nova 平台 API
    oapi-client.ts        # 共享的 Nova OpenAPI HTTPClient 实例
    nova-config.ts        # 读取 .nova/config.json提供 getDefaultAgentId()
    info/route.ts         # 返回客户端配置agentId, conversationId, wssUrl, token
    chat/event/route.ts   # 代理获取聊天事件历史
    chat/stop/route.ts    # 停止当前任务
    conversation/route.ts # 会话列表
    file/upload/route.ts  # 文件上传
    file/sign/route.ts    # 文件签名 URL
    health/route.ts       # 健康检查

components/
  nova-sdk/               # 核心聊天 SDK
    types.ts              # 核心类型定义ApiEvent, PlatformConfig, TaskArtifact 等)
    websocket.ts          # WebSocket 客户端(自动重连、心跳、离线队列)
    store/
      useNovaStore.ts     # Zustand 全局状态events, artifacts, ws 状态, loading
    context/
      context.ts          # NovaContext 定义HTTPClient + getArtifactUrl
      Provider.tsx         # Context Provider
      useNova.ts          # useContext hook
    hooks/
      useNovaChatLogic.ts # 主编排 hook组合所有子 hook
      useNovaEvents.ts    # WebSocket + 历史事件获取
      useNovaService.ts   # 从 platformConfig 创建 HTTPClient
      useMessageSender.ts # 通过 WebSocket 发送消息
      useEventProcessor.ts # ApiEvent → UI 消息转换
      useBuildConversationConnect.ts # 初始化:获取 agentId、conversationId
      useFileUploader.ts  # 文件上传逻辑
      useAttachmentHandlers.ts # 附件点击处理
      useMessageScroll.ts # 消息列表自动滚动
      usePanelState.ts    # 产物面板开关
      useSize.ts          # 响应式尺寸
    nova-chat/            # 聊天主组件
      index.tsx           # NovaChat包裹 Provider、Header、MessageList、Input、TaskPanel
      ChatHeader.tsx      # 聊天头部
      ChatInputArea.tsx   # 输入区域
    message-list/         # 消息列表
      index.tsx           # MessageList
      MessageItem.tsx     # 单条消息
      AttachmentItem.tsx  # 文件附件
      ImageAttachmentItem.tsx # 图片附件
      ToolCallAction.tsx  # 工具调用展示
    message-input/        # 消息输入
      index.tsx           # 输入组件
      FilePreviewList.tsx # 文件预览列表
    task-panel/           # 产物预览面板
      index.tsx           # TaskPanel侧边栏50% 宽度)
      ArtifactList.tsx    # 产物列表
      ArtifactPreview.tsx # 产物预览
      Preview/            # 各类预览组件Markdown、代码、PPT、工具调用
  ui/                     # 基础 UI 组件Shadcn 风格)
    button.tsx, dialog.tsx, scroll-area.tsx, image.tsx, image-preview.tsx

http/
  index.ts                # HTTPClient 类Fetch 封装)
  http.ts                 # 底层 fetch 包装,支持 onRequest/onResponse/onError 钩子
  type.ts                 # HTTP 类型定义

db/
  index.ts                # Drizzle ORM 连接server-only全局单例

utils/
  logger.ts               # Winston 日志(开发→终端,生产→按天文件轮转)
  cn.ts                   # clsx + tailwind-merge 工具函数

数据流

app/page.tsx
  │  useBuildConversationConnect() → GET /api/info
  │  获取 agentId来自 .nova/config.json, conversationId, platformConfig
  ▼
NovaChat 组件
  │  useNovaChatLogic() 编排所有子 hook
  ├── useNovaEvents()    → WebSocket 连接 + GET /api/chat/event 加载历史
  ├── useMessageSender() → WebSocket 发送消息
  └── useEventProcessor()→ 事件转 UI 消息
  ▼
Zustand Store (useNovaStore)
  │  events[], artifacts[](从 events 自动提取), loading, ws 状态
  ▼
MessageList / TaskPanel 渲染

API 路由

路由 方法 说明
/api/info GET 返回客户端配置agentId, conversationId, wssUrl, token
/api/chat/event GET 代理 Nova /chat/event_list,获取事件历史
/api/chat/stop POST 停止当前任务
/api/conversation GET 会话列表
/api/file/upload POST 上传文件
/api/file/sign POST 获取文件签名 URL
/api/health GET 健康检查

所有 API 路由通过 app/api/oapi-client.ts 中的共享 HTTPClient 代理到 Nova 平台,请求头自动注入 Tenant-IdAuthorization。Agent ID 从 .nova/config.json 读取,不再依赖环境变量。

WebSocket 消息格式

  • 心跳:{ message_type: 'ping' }
  • 聊天消息:{ message_type: 'chat', conversation_id, content, ... }
  • 切换会话:{ message_type: 'switch_conversation', conversation_id }

WebSocket 客户端内置自动重连(可配置次数/间隔)、心跳检测、网络状态监听、页面可见性恢复。

常用命令

pnpm install          # 安装依赖
pnpm dev              # 启动开发服务器(端口 13000
pnpm build            # 生产构建
pnpm start            # 生产运行(端口 13000
pnpm lint             # ESLint 检查并自动修复
pnpm db:generate      # 生成 Drizzle 迁移
pnpm db:migrate       # 执行数据库迁移
pnpm db:studio        # 打开 Drizzle Studio GUI

环境变量

参考 .env.example,在项目根目录创建 .env.local

变量名 说明
DATABASE_URL PostgreSQL 连接地址Drizzle 使用)
LOG_DIR 生产环境日志目录(默认 ./logs,按天切分)
NOVA_BASE_URL Nova OpenAPI 服务地址
NOVA_TENANT_ID 租户 ID请求头 Tenant-Id
NOVA_ACCESS_KEY 鉴权密钥(请求头 Authorization

Agent ID 已从环境变量迁移至 .nova/config.json,无需在 .env.local 中配置。

代码约定

  • 路径别名@/*./*tsconfig paths
  • 组件PascalCase 文件名,使用 React.memo() 优化
  • HookscamelCaseuse* 前缀
  • 工具函数camelCase
  • 常量枚举UPPER_SNAKE_CASEEventType, TaskStatus
  • 样式Tailwind CSS 工具类,通过 cn() 函数(utils/cn.ts)合并类名
  • 回调稳定性:使用 ahooks 的 useMemoizedFn()useCallback()
  • 异步状态queueMicrotask() 延迟更新,避免 React 批量更新冲突
  • Store 去重Zustand store 按 event_id 去重事件
  • 日志:开发环境输出到终端,生产环境按天写入 ${LOG_DIR}/app-YYYY-MM-DD.log
  • 数据库:所有操作通过 Drizzle ORMimport { db } from '@/db',仅限 server 端
  • UI 错误提示:使用中文(如 "Chat 不可用,请检查项目 .env 配置"
  • 请求头约定X-Locale=zh, X-Region=CN

注意事项

  • next.config.tsreactStrictMode: false
  • .next/ 目录为构建产物,不要手动修改
  • 数据库连接使用全局单例模式,db/index.ts 标记了 server-only
  • 聊天初始化流程:先请求 /api/info 获取配置 → 再建立 WebSocket → 加载历史事件
  • 产物提取来源:attachments, attachment_files, files, generated_files,按文件 key 去重
  • 文件签名通过 getArtifactUrl() 懒加载POST /file/sign,失败时 fallback 到原始路径
Description
No description provided
Readme 13 MiB
Languages
TypeScript 98.4%
CSS 1.5%