feat: 工作台聊天室功能

This commit is contained in:
2026-05-31 02:37:23 +08:00
parent 83cf9eab94
commit f83f434863
33 changed files with 2520 additions and 265 deletions

View File

@@ -20,9 +20,12 @@ src/
projects.ts 项目数据访问函数
providers.ts 供应商数据访问函数
models.ts 模型数据访问函数
conversations.ts 会话数据访问函数
index.ts 数据库模块导出
ai/ AI 服务层
types.ts AI 配置类型定义
registry.ts AI Provider Registry 构建与连接测试
agent-stream.ts AI Agent 流式调用
dev.ts 开发模式启动入口
main.ts 生产模式启动入口
server.ts HTTP server 启动工厂Bun.serve routes 声明式路由)
@@ -34,6 +37,7 @@ src/
routes/ API 路由处理器
providers/ 供应商 CRUD 路由
models/ 模型 CRUD 路由
chat/ 聊天会话与消息路由
shared/
api.ts 前后端共享 TypeScript 类型定义
app.ts 应用全局常量name、title、subtitle、description
@@ -101,7 +105,7 @@ Request
| `src/server/server.ts` | Bun HTTP server 和 routes 注册 |
| `src/server/routes/` | API handler按端点拆分 |
| `src/server/db/` | SQLite 连接、schema、migration 和 data access |
| `src/server/ai/` | AI Provider Registry 构建与连接测试 |
| `src/server/ai/` | AI Provider Registry 构建与 Agent 流式调用 |
| `src/server/config/` | 配置解析模块types、variables、schema |
| `src/web/` | React 前端 |
| `src/shared/api.ts` | 前后端共享 API 类型 |

View File

@@ -62,7 +62,7 @@ middleware.ts 提供 API 参数校验函数:
### 数据访问
`src/server/db/projects.ts` 提供项目数据访问函数,`src/server/db/providers.ts` 提供供应商数据访问函数,`src/server/db/models.ts` 提供模型数据访问函数。输入输出使用 `src/shared/api.ts` 的类型。函数内部使用 Drizzle query builder 包装 `bun:sqlite` Database。
`src/server/db/projects.ts` 提供项目数据访问函数,`src/server/db/providers.ts` 提供供应商数据访问函数,`src/server/db/models.ts` 提供模型数据访问函数`src/server/db/conversations.ts` 提供会话和消息数据访问函数。输入输出使用 `src/shared/api.ts` 的类型。函数内部使用 Drizzle query builder 包装 `bun:sqlite` Database。
## AI 服务层
@@ -85,6 +85,10 @@ middleware.ts 提供 API 参数校验函数:
每次 AI 调用时从 DB 查询 providers构建 registry 后通过 `registry.languageModel('providerId:modelId')` 获取模型实例。不使用缓存层。模型是否存在以及业务能力标签由调用方基于 models 表先行校验registry 只负责将 providerId/modelId 映射到 AI SDK 模型实例。
### Agent 流式调用
`src/server/ai/agent-stream.ts` 提供 `agentStream(options)` 函数,封装 Vercel AI SDK `streamText` 调用。接收数据库实例、消息数组和模型 DB ID从 DB 查询模型与供应商信息后构建 Provider Registry使用 `:` 作为 provider 和 modelId 的分隔符。默认使用 `stepCountIs(1)` 限制单步调用。返回 `StreamTextResult`,路由层通过 `result.toUIMessageStreamResponse()` 转为 SSE 响应。
### 供应商连通性测试
供应商连通性测试返回 `{ providerTestResponse: { ok, message } }`,前端根据 `ok` 展示成功或失败提示。
@@ -102,6 +106,21 @@ middleware.ts 提供 API 参数校验函数:
| `anthropic` | `createAnthropic({ apiKey, baseURL })` |
| `openai-compatible` | `createOpenAICompatible({ name, apiKey, baseURL })` |
## 聊天 API
聊天 API 按项目维度组织会话和消息:
| 方法 | 路径 | 说明 |
| ------ | ----------------------------------------------- | ------------------ |
| GET | `/api/projects/:id/conversations` | 列出项目下所有会话 |
| POST | `/api/projects/:id/conversations` | 创建新会话 |
| GET | `/api/projects/:id/conversations/:cid` | 获取会话详情 |
| DELETE | `/api/projects/:id/conversations/:cid` | 删除会话及其消息 |
| GET | `/api/projects/:id/conversations/:cid/messages` | 获取会话消息列表 |
| POST | `/api/projects/:id/chat` | 发送消息并流式回复 |
聊天路由处理器位于 `src/server/routes/chat/`,遵循统一的 handler 模式。`send.ts` 处理发送消息:验证会话归属后保存用户消息到 DB调用 `agentStream` 获取流式响应,返回 SSE UI 消息流,流结束后后台保存 AI 回复到 DB。
## 类型规范
- 共享类型以 src/shared/api.ts 为唯一源头

View File

@@ -6,14 +6,15 @@
## 技术栈
| 层面 | 技术 | 用途 |
| ------ | --------------------------------------------------- | ------------------------ |
| 框架 | React 19 | UI 组件开发 |
| 构建 | Vite开发+ Bun compile生产 | 开发服务 HMR 与生产构建 |
| 语言 | TypeScript | 类型安全 |
| UI 库 | Ant Design (antd) + @ant-design/icons | UI 组件图标 |
| 数据层 | TanStack Query (React Query) + React Query Devtools | 服务端状态管理与自动刷新 |
| 路由 | React Router v7 (Declarative mode) | SPA 路由与页面导航 |
| 层面 | 技术 | 用途 |
| ------ | ----------------------------------------------------- | ------------------------ |
| 框架 | React 19 | UI 组件开发 |
| 构建 | Vite开发+ Bun compile生产 | 开发服务 HMR 与生产构建 |
| 语言 | TypeScript | 类型安全 |
| UI 库 | Ant Design (antd) + @ant-design/icons + @ant-design/x | UI 组件图标与聊天 UI |
| 数据层 | TanStack Query (React Query) + React Query Devtools | 服务端状态管理与自动刷新 |
| AI 层 | Vercel AI SDK (`@ai-sdk/react`) | 聊天状态管理与流式通信 |
| 路由 | React Router v7 (Declarative mode) | SPA 路由与页面导航 |
不引入额外状态管理库。TanStack Query 承担服务端状态,组件内状态使用 useState。
@@ -123,7 +124,7 @@ token 和 CSS 变量规则:
前端提供两个入口外壳,共享通用 Console Shell 组件:
- **Admin管理台**`src/web/consoles/admin/AdminConsoleLayout.tsx`,菜单配置在 `menu.tsx`,路由 `/``/projects``/models`
- **Workbench工作台**`src/web/consoles/workbench/WorkbenchProjectGate.tsx``WorkbenchConsoleLayout.tsx`,菜单配置和路由构造在 `routes.ts`,路由 `/workbench/:projectId`
- **Workbench工作台**`src/web/consoles/workbench/WorkbenchProjectGate.tsx``WorkbenchConsoleLayout.tsx`,菜单配置和路由构造在 `routes.ts`,路由 `/workbench/:projectId`默认菜单为"聊天室",使用 `ChatPage` 作为主页面。
通用 Console Shell`src/web/components/ConsoleShell/ConsoleShell.tsx`)包含 Layout、Header、Sider、Content、主题切换、版本展示和侧边栏折叠状态由 Admin 和 Workbench 复用。Header 显示品牌名、版本号和控制台标题Admin 显示"管理台"Workbench 显示"工作台 · 项目名")。
@@ -135,6 +136,15 @@ Workbench 项目上下文通过 `ProjectContext` 提供,在 `WorkbenchProjectG
供应商表单必须支持未保存配置的连通性测试,新建供应商时 type 默认 `openai-compatible`baseURL 不设默认值。连通性测试返回 `ok: false` 时应展示失败反馈,不得使用成功提示样式;`/models` 不支持或响应格式不兼容属于可忽略提醒,不得阻止保存。
### 聊天页面
Workbench 聊天页面位于 `src/web/consoles/workbench/pages/ChatPage.tsx`,组合 `ChatSidebar``ChatPanel` 两个子组件。
- **ChatSidebar**:使用 TanStack Query 管理会话列表,提供创建和删除会话操作。
- **ChatPanel**:使用 Vercel AI SDK `useChat` hook来自 `@ai-sdk/react`)管理聊天状态,通过 `DefaultChatTransport`(来自 `ai` 包)与后端 SSE 端点通信。使用 `@ant-design/x``Bubble.List``Sender` 组件渲染消息列表和输入框。`useChat` 返回的 `UIMessage` 使用 `parts` 数组存储内容,不包含 `content` 属性;需从 `parts` 中提取 `type: "text"` 的文本内容用于 Bubble 展示。
- **MessageBubble**简单的纯文本消息气泡组件MVP
- **use-conversations hook**:位于 `src/web/hooks/use-conversations.ts`,封装会话 CRUD 的 fetch 调用。
- 生产入口必须启用 `ErrorBoundary`,运行时渲染异常使用 antd `Result status="500"` 或等价组件展示。
- `ReactQueryDevtools` 仅在 `import.meta.env.DEV` 条件下渲染,不进入生产渲染路径。
- 主题切换统一通过 `ConfigProvider` 的 antd theme algorithm 控制,不使用硬编码主题色。

View File

@@ -32,19 +32,19 @@ bun run dev config.yaml
## 功能介绍
| 功能 | 路径 | 说明 |
| ---------- | ----------------------- | ---------------------------------------- |
| 总览 | `/` | Admin 管理台总览,展示运行时元信息 |
| 项目管理 | `/projects` | 创建、编辑、归档、恢复和永久删除项目 |
| 模型管理 | `/models` | 配置 AI 供应商和模型,供后续 AI 功能使用 |
| 工作台总览 | `/workbench/:projectId` | Workbench 工作台总览,按项目维度查看信息 |
| 用户管理 | `/users` | 页面建设中 |
| 系统设置 | `/settings` | 页面建设中 |
| 功能 | 路径 | 说明 |
| -------- | ----------------------- | ---------------------------------------- |
| 总览 | `/` | Admin 管理台总览,展示运行时元信息 |
| 项目管理 | `/projects` | 创建、编辑、归档、恢复和永久删除项目 |
| 模型管理 | `/models` | 配置 AI 供应商和模型,供后续 AI 功能使用 |
| 聊天室 | `/workbench/:projectId` | Workbench 工作台聊天室,与 AI 对话 |
| 用户管理 | `/users` | 页面建设中 |
| 系统设置 | `/settings` | 页面建设中 |
平台提供两个入口:
- **Admin管理台**:全局管理视角,包含总览和项目管理。默认入口,访问 `/` 即可进入。
- **Workbench工作台**:项目维度视角,通过 `/workbench/:projectId` 进入指定项目的工作台。URL 可保存为浏览器书签,下次直接进入。仅 active 状态的项目可进入工作台archived 项目不可访问。
- **Workbench工作台**:项目维度视角,通过 `/workbench/:projectId` 进入指定项目的工作台。默认进入聊天室页面,可与已配置的 AI 模型进行对话。URL 可保存为浏览器书签,下次直接进入。仅 active 状态的项目可进入工作台archived 项目不可访问。
从项目管理页面的 active 项目行可点击"工作台"跳转到对应项目的工作台。
@@ -55,4 +55,10 @@ bun run dev config.yaml
- **供应商**:新增、编辑、删除 OpenAI、Anthropic 或 OpenAI 兼容供应商。新建供应商时类型默认是 `openai-compatible`baseURL 和 API Key 由用户填写。
- **模型**:为供应商新增模型,填写模型显示名称、实际调用用的 modelId、能力标签以及可选的上下文长度和最大输出 token。
供应商表单提供测试连接操作:系统先测试 Base URL 是否可达,再尝试请求 `/models` 验证 API Key 和模型列表接口。若服务不支持 `/models`,页面会提示接口可达但可能不支持模型列表;该结果只作为提醒,不会阻止保存供应商或模型。删除供应商前必须先删除或迁移其关联模型,否则系统会拒绝删除以避免误删模型配置。
供应商表单提供"测试连接"操作:系统先测试 Base URL 是否可达,再尝试请求 `/models` 验证 API Key 和模型列表接口。若服务不支持 `/models`,页面会提示接口可达但可能不支持模型列表;该结果只作为提醒,不会阻止保存供应商或模型。删除供应商前必须先删除或迁移其关联模型,否则系统会拒绝删除以避免误删模型配置。
## 聊天室
在 Workbench 工作台中,默认进入聊天室页面。左侧为会话列表,可新建和删除会话;右侧为聊天面板,输入消息后 AI 将流式回复。
使用聊天功能前,需先在 Admin 管理台的模型管理页面配置至少一个 AI 供应商和模型。新建会话时系统会自动选择第一个可用模型。