refactor(template): 优化模板管理与服务注入,增强错误处理并添加故障排除清单

- 添加模板管理故障排除清单,以帮助用户解决模板管理中遇到的常见问题。
- 统一服务注入逻辑,移除不必要的props定义,增强错误处理机制。
- 优化模板管理,统一服务注入与存储键管理。
- 更新 `TemplateSelect.vue`,移除 `services` prop,改用 `inject` 注入服务。
- 整合 `useTemplateManager`,统一模板选择保存逻辑及存储键管理。
- 新增 `storage-keys.ts`,集中管理存储键常量,避免重复定义,便于维护与遍历。
- 更新相关组件以适配新的模板管理方式,确保模板选择状态正确保存和恢复。
- 修正了模板类型错误的问题,确保在管理界面切换分类后添加的模板类型与当前显示的分类一致。
- 修复了模板管理器打开位置错误的问题,确保从不同入口打开模板管理器时,定位到正确的分类。
- 优化了模板保存和导入逻辑,增加了错误处理和提示。
- 确保所有异步模板操作都使用了 `await` 关键字,避免潜在的时序问题。
- 移除了 `usePromptOptimizer` 中 `selectedOptimizationMode` 的默认值,强制传入该参数。
- 优化了 `TemplateSelect` 组件中 `optimizationMode` prop 的处理,设为 `required`。
This commit is contained in:
linshen
2025-06-29 10:10:26 +08:00
parent 3abc01b7c4
commit acf592ab2c
74 changed files with 3503 additions and 1739 deletions

49
docs/developer/README.md Normal file
View File

@@ -0,0 +1,49 @@
# 开发者文档
欢迎参与Prompt Optimizer的开发这里包含了所有开发相关的技术文档。
## 🚀 快速开始
- 快速开始指南(待创建) - 开发环境搭建和项目启动
- [技术开发指南](./technical-development-guide.md) - 完整的技术栈和开发规范
- [项目结构](./project-structure.md) - 项目文件和目录组织说明
- [AI开发流程规范](./ai-development-workflow.md) - AI辅助开发的标准化流程
- [通用开发经验](./general-experience.md) - 项目开发中的通用经验与最佳实践
## 📱 平台开发指南
### 桌面端
- [桌面开发指南](./desktop-developer-guide.md) - Electron桌面应用开发
### Web端
- Web开发指南待创建 - Web应用开发说明
### 浏览器插件
- 插件开发指南(待创建) - Chrome扩展开发
## 📚 API文档
- [核心API文档](./api/core-api.md)(待创建) - @prompt-optimizer/core包API参考
## 🏗️ 架构文档
- [架构概览](./architecture/overview.md)(待创建) - 系统整体架构
- [设计模式](./architecture/design-patterns.md)(待创建) - 项目中使用的设计模式
## 🔧 故障排查
- [通用排查清单](./troubleshooting/general-checklist.md) - 常见问题的排查步骤
- [排查指南索引](./troubleshooting/README.md)(待创建) - 所有排查文档的索引
## 🤝 贡献指南
- 贡献指南(待创建) - 如何参与项目开发
- 代码规范(在技术开发指南中) - 编码标准和最佳实践
- 提交规范(待创建) - Git提交消息规范
## 📋 开发流程
- [开发任务清单](./todo.md) - 按功能模块和优先级组织的任务列表
- 开发流程(待创建) - 从需求到发布的完整流程
- 测试指南(待创建) - 单元测试和集成测试
- 发布流程(待创建) - 版本发布和部署流程

View File

@@ -0,0 +1,158 @@
# AI开发工作流程
workspace工作区使用和文档管理的实际操作流程。
## 🚀 开始新任务
### 1. 查询背景信息
- 查看 `docs/archives/README.md` 寻找相关历史经验
- 查看 `docs/developer/todo.md` 了解当前开发任务状态
- 查看 `docs/developer/project-structure.md` 了解项目结构
- 需要时参考其他docs文档主要用于参考不是必须
### 2. 检查workspace状态
- 确认workspace是否干净应该只有模板文件
- 如果workspace混乱先执行清理流程
- 确保workspace使用标准模板结构
### 3. 设置新任务在workspace中
-`scratchpad.md` 中替换模板内容:
```markdown
### [新功能名称] - [开始日期]
**目标**: [具体目标描述]
**状态**: 进行中
#### 计划步骤
[ ] 1. 需求分析
[ ] 2. 技术方案设计
[ ] 3. 功能实现
[ ] 4. 测试验证
[ ] 5. 文档更新
```
- 在 `todo.md` 中添加紧急任务和重要任务
## 🔄 迭代开发
### 开发循环(重复执行)
1. **记录进展** - 在 `scratchpad.md` 中更新进度记录
2. **实现功能** - 编写代码,运行测试
3. **记录发现** - 重要经验写入 `experience.md`
4. **更新状态** - 标记完成的步骤 `[x]`
5. **管理任务** - 在 `todo.md` 中更新任务状态
### 参考文档(按需查看)
- 查看 `docs/developer/general-experience.md` 获取通用经验
- 查看 `docs/developer/` 下的技术文档
- 查看相关 `docs/archives/` 目录获取专项经验
## ✅ 完成任务
### 1. 总结工作
在scratchpad.md中添加
```markdown
### 完成总结
- 实现了什么功能
- 遇到了什么问题
- 如何解决的
```
### 2. 归档决策(简单判断)
**问自己4个问题**
- 功能完成了吗? → 是 → 归档
- 有重要经验吗? → 是 → 归档
- workspace太乱了吗 → 是 → 整理
- 有未完成任务吗? → 是 → 转移到developer/todo.md
## 📁 归档操作
### 快速归档流程
1. **创建目录** - `docs/archives/[下一个编号]-[功能名称]/`
2. **提取内容** - 从workspace文件中提取相关内容
3. **创建文档** - README.md概述+ 具体实现文档
4. **更新索引** - 在archives/README.md中添加条目
5. **转移任务** - 未完成任务转移到developer/todo.md
6. **转移经验** - 通用经验转移到developer/general-experience.md
7. **重置workspace** - 使用模板完全重置
### workspace深度清理流程
1. **分析内容** - 识别已完成任务、未完成任务、通用经验、专项经验
2. **按功能归档** - 将相关内容归档到对应的archives目录
3. **任务转移** - 将未完成任务按功能模块和优先级整理到developer/todo.md
4. **经验提取** - 将通用经验提取到developer/general-experience.md
5. **模板重置** - 删除workspace所有文件从workspace-template复制模板文件
## 📚 日常维护
### 查询历史
- 先看 `docs/archives/README.md` 找功能点
- 再看具体目录的README.md了解概况
- 最后看implementation.md和experience.md获取细节
### 保持整洁
- 每周检查workspace状态及时清理过期内容
- 完成重要任务后立即归档
- 定期将未完成任务转移到developer/todo.md
- 使用模板重置保持workspace干净
## 🧹 Workspace整理最佳实践
### 整理触发条件
- workspace文件超过200行
- 包含3个以上已完成任务
- 混合了多个不同功能的内容
- 准备开始新的重要任务
### 整理步骤模板
1. **内容分析** - 识别已完成、进行中、计划中的内容
2. **功能分类** - 按功能点对内容进行分组
3. **创建归档** - 为已完成功能创建archives目录
4. **任务转移** - 按优先级整理未完成任务到developer/todo.md
5. **经验提取** - 将通用经验整理到developer/general-experience.md
6. **模板重置** - 使用标准模板完全重置workspace
### 整理质量检查
- ✅ workspace只包含3个模板文件
- ✅ 所有历史任务已正确归档
- ✅ 未完成任务已转移到developer/todo.md
- ✅ archives/README.md已更新索引
- ✅ 交叉引用链接正确
## 🔄 工作流自我改进
### 改进原则
- **保持简洁** - 避免过度膨胀控制在200行以内
- **基于实践** - 根据实际执行经验调整流程
- **定期评估** - 每次功能流程结束后评估一次工作流效果
### 改进触发
当出现以下情况时,考虑更新此工作流:
- 发现流程步骤不合理或缺失
- workspace使用模式发生变化
- 归档决策标准需要调整
- 新的最佳实践出现
### 改进记录
在 `docs/developer/general-experience.md` 中记录工作流改进想法,定期整合到此文档。
## 🛠️ 实用工具命令
### workspace模板重置
```bash
# Windows
del docs\workspace\*.md
copy docs\workspace-template\*.md docs\workspace\
ren docs\workspace\scratchpad-template.md scratchpad.md
ren docs\workspace\todo-template.md todo.md
ren docs\workspace\experience-template.md experience.md
```
### 快速检查workspace状态
- 文件数量应该是3个scratchpad.md, todo.md, experience.md
- 内容应该是模板格式,包含占位符如 `[任务名称]`、`[日期]` 等
- 如果包含具体任务内容,说明需要清理
---
**自迭代版本**: v4.0
**更新时间**: 2025-07-01
**特点**: 基于实际整理经验优化,增加深度清理流程和实用工具

View File

@@ -0,0 +1,255 @@
# Prompt Optimizer 桌面应用开发者指南
## 1. 项目背景与目标
用户希望将现有的 Prompt Optimizer Web 应用改造为桌面端应用,其核心目标是**利用 Electron 主进程代理 API 请求,从而彻底解决浏览器的 CORS 跨域问题**。
### 技术选型:为何选择 Electron
- **技术栈统一**: Electron 允许我们复用现有的 JavaScript/TypeScript 和 Vue 技术栈,无需引入 Rust (Tauri 方案) 等新技术,降低了团队的学习成本和开发门槛。
- **最小化代码侵入**: 通过 Electron 的进程间通信IPC机制我们可以实现一个无缝的 API 请求代理,仅需在 SDK 初始化时注入一个自定义的网络请求函数,对核心业务逻辑 (`packages/core`) 的侵入极小。
- **生态成熟**: Electron 拥有庞大而成熟的社区和生态系统,为未来的功能扩展(如自动更新、系统通知)提供了强有力的保障。
## 2. 架构设计
应用采用**高层服务代理**架构,职责清晰,维护性强。主进程作为后端服务提供者,渲染进程作为前端消费者。
### 整体架构图
```
┌─────────────────────────────────────────────────────────────┐
│ Electron 桌面应用 │
├─────────────────────────────────────────────────────────────┤
│ 主进程 (main.js) - 服务端 │
│ - 窗口管理 │
│ - **直接消费 @prompt-optimizer/core 包** │
│ - **实例化并持有核心服务 (LLMService, ModelManager)** │
│ - **作为后端,通过 IPC 提供高层服务接口 (如 testConnection)** │
├─────────────────────────────────────────────────────────────┤
│ 预加载脚本 (preload.js) - 安全桥梁 │
│ - 将主进程的高层服务接口 (`llm.testConnection`) │
│ - 安全地暴露给渲染进程 (`window.electronAPI.llm.*`) │
├─────────────────────────────────────────────────────────────┤
│ 渲染进程 (Vue 应用) - 纯前端消费者 │
│ - UI 界面与用户交互 │
│ - **通过 `core` 包中的代理对象 (`ElectronLLMProxy`)** │
│ - **调用 `window.electronAPI.llm.testConnection()`** │
│ - **不直接处理网络请求,只调用定义好的服务接口** │
└─────────────────────────────────────────────────────────────┘
```
### 服务调用数据流
```
1. 用户在UI上操作触发 Vue 组件中的方法
2. Vue 组件调用 `core` 包中面向 Electron 的代理服务 (`ElectronLLMProxy`)
3. 代理服务调用预加载脚本暴露的 `window.electronAPI.llm.testConnection()` (IPC 调用)
4. 预加载脚本通过 `ipcRenderer` 将请求发送给主进程
5. 主进程的 `ipcMain` 监听器捕获请求,直接调用**主进程中持有的真实 LLMService 实例**
6. LLMService 实例在 Node.js 环境中,使用 `node-fetch` 发起真实的 API 请求
7. 最终结果 (JSON 数据,非 Response 对象) 沿原路返回:主进程 → 预加载脚本 → 代理服务 → Vue 组件 → UI 更新
```
### 核心架构详解:代理模式与进程间通信 (IPC)
为了深刻理解新架构的健壮性,必须理解其背后的核心理念:**主进程是"大脑",渲染进程是"四肢"**。所有的记忆、思考和决策(核心服务)都必须由"大脑"统一做出,而"四肢"UI只负责感知和行动。
#### 1. 为何不能在UI层直接调用 `core` 模块?
在纯Web应用中UI和Core生活在同一个世界里单进程可以直接通信。但在Electron中主进程和渲染进程是两个**完全隔离的操作系统进程**,拥有各自独立的内存空间。
如果在UI层渲染进程直接调用 `createModelManager()`,会发生什么?
- **数据孤岛**:会在渲染进程中创建一个**全新的、空白的**`ModelManager`实例。它与主进程中那个拥有真实数据的实例**互不相通**,导致数据永远无法同步。
- **能力缺失**`core`模块的部分功能如未来要实现的文件读写依赖于Node.js环境。渲染进程基于Chromium没有这些能力调用相关功能将直接导致**应用崩溃**。
#### 2. `ipcRenderer` 与 `ipcMain`:两个世界的电话
进程间通信IPC是连接这两个隔离世界的唯一桥梁。
- **`ipcRenderer`**: 安装在**渲染进程**的"电话",专门用于向主进程"打电话"(发起请求)。
- **`ipcMain`**: 安装在**主进程**的"总机",专门用于"接电话"(处理请求)。
我们主要使用`invoke`/`handle`这种**双向通信**模式,它完美地模拟了"请求-响应"的异步流程。
#### 3. `ElectronModelManagerProxy`:优雅的"全权代理"
直接让UI层去操作`ipcRenderer.invoke('channel-name', ...)`这种底层的"电话指令"是混乱且不安全的。为此,我们引入了**代理模式 (Proxy Pattern)**。
`ElectronModelManagerProxy`这类代理类的核心作用是**"假装"自己是真正的 `ModelManager`**从而让UI层的代码可以像以前一样无缝调用无需关心背后复杂的跨进程通信。
它的工作流程是一场精密的"拦截-转发-返回"
1. **UI调用**UI调用`modelManager.getModels()`
2. **Proxy拦截**:实际上调用的是`ElectronModelManagerProxy`实例的同名方法。
3. **Proxy转发**:该方法不包含业务逻辑,只负责通过`preload.js`暴露的`electronAPI`,最终调用`ipcRenderer.invoke('model-getModels')`
4. **主进程处理**`ipcMain.handle`捕获请求,调用**主进程中唯一的、真实的`ModelManager`实例**,处理并返回数据。
5. **数据返回**结果沿原路返回最终交付给UI组件。
这个模式虽然在新增方法时需要在多个文件(`main.js`, `preload.js`, `proxy.ts`)中添加"样板代码",但这并非无意义的重复,而是为了换取**单一数据源、安全的边界和优雅的类型安全抽象**所付出的、性价比极高的代价。
## 3. 快速启动 (开发模式)
### 系统要求
- Windows 10/11, macOS, or Linux
- Node.js 18+
- pnpm 8+
### 启动步骤
```bash
# 1. (首次) 在项目根目录安装所有依赖
pnpm install
# 2. 运行桌面应用开发模式
pnpm dev:desktop
```
此命令将同时启动 Vite 开发服务器(用于前端界面)和 Electron 应用实例,并开启热重载。
## 4. 核心技术实现
当前架构放弃了脆弱的底层 `fetch` 代理,转向更稳定、更易于维护的**高层服务代理模型**。
### 服务消费模型
主进程 (`main.js`) 现在作为后端服务,直接消费 `packages/core` 的能力,完全复用其业务逻辑,避免了代码冗余。
```javascript
// main.js - 主进程直接导入并使用 core 包
const {
createLLMService,
createModelManager,
// ... 其他服务
} = require('@prompt-optimizer/core');
// 在主进程启动时实例化服务
let llmService;
app.whenReady().then(() => {
// 此处需要一个适合 Node.js 的存储方案 (见下文)
const modelManager = createModelManager(/* ... */);
// 创建一个在 Node.js 环境中运行的真实 LLMService 实例
llmService = createLLMService(modelManager);
// 将服务实例传递给 IPC 设置函数
setupIPC(llmService);
});
```
### 高层 IPC 接口
渲染进程与主进程之间的通信"契约",从不稳定的 `fetch` API 升级为我们自己定义的、稳定的 `ILLMService` 接口。
```javascript
// main.js - 提供服务接口
function setupIPC(llmService) {
ipcMain.handle('llm-testConnection', async (event, provider) => {
try {
await llmService.testConnection(provider);
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
});
// ... 其他接口的实现
}
// preload.js - 暴露服务接口
contextBridge.exposeInMainWorld('electronAPI', {
llm: {
testConnection: (provider) => ipcRenderer.invoke('llm-testConnection', provider),
// ... 其他接口的暴露
}
});
```
### 存储策略
由于渲染进程的 `IndexedDB` 在主进程 (Node.js) 中不可用,我们为桌面端设计了分阶段的存储方案:
- **第一阶段 (当前实现):** 采用一个临时的**内存存储**方案。这使得新架构可以快速运行起来,但应用关闭后数据会丢失。
- **第二阶段 (未来计划):** 实现一个**文件存储 (`FileStorageProvider`)**,将模型、模板等数据以 JSON 文件的形式持久化存储在用户本地磁盘上,充分利用桌面环境的优势。
## 5. 构建与部署
### 开发脚本
- `pnpm dev:desktop`: 同时启动前端开发服务器和 Electron 应用,用于日常开发。
- `pnpm build:web`: 仅构建前端 Web 应用,产物输出到 `packages/desktop/web-dist`
- `pnpm build:desktop`: 构建最终的可分发桌面应用程序(如 `.exe``.dmg`)。
### 生产版本构建流程
```bash
# 完整构建流程,将自动先构建 web 内容
pnpm build:desktop
# 构建完成后,可执行文件位于以下目录
# packages/desktop/dist/
```
### Electron Builder 配置
打包配置位于 `packages/desktop/package.json``build` 字段中。
```json
{
"build": {
"appId": "com.promptoptimizer.desktop",
"productName": "Prompt Optimizer",
"directories": { "output": "dist" },
"files": [
"main.js",
"preload.js",
"web-dist/**/*", // 将构建好的前端应用打包进去
"node_modules/**/*"
],
"win": {
"target": "nsis", // Windows 安装包格式
"icon": "icon.ico" // 应用图标
}
}
}
```
## 6. 故障排除
**1. 应用启动失败或界面空白**
- 确保 `pnpm install` 已成功执行。
- 确认 `pnpm build:web` 是否成功执行,并且 `packages/desktop/web-dist` 目录已生成且内容不为空。
- 尝试清理并重新安装: `pnpm store prune && pnpm install`
**2. Electron 安装不完整**
- 这通常是网络问题。可以尝试配置 `electron_mirror` 环境变量或手动安装。
- 手动安装命令:
```bash
# (路径可能因 pnpm 版本而异)
cd node_modules/.pnpm/electron@<version>/node_modules/electron
node install.js
```
**3. API 调用失败**
- 检查 API 密钥是否在桌面应用的 "模型管理" 页面中正确配置。
- 打开开发者工具 (`Ctrl+Shift+I`) 查看渲染进程的 `Console`。
- **关键:** 由于核心 API 调用逻辑已移至主进程,请务必**检查启动桌面应用的终端(命令行窗口)中的日志输出**,那里会包含最直接的 `node-fetch` 错误信息。
- 确认网络连接正常。
## 7. 未来架构改进方向
当前手动维护多个文件的IPC"样板代码"是清晰和健壮的,但随着功能扩展,开发效率和一致性会成为挑战。未来,我们可以采用**代码生成 (Code Generation)**的方案来彻底解决这个问题。
### 核心理念
我们唯一的、需要手动维护的文件,应该是服务的**接口定义**(例如 `IModelManager`)。我们将这个接口作为**"单一事实源" (Single Source of Truth)**。
### 自动化工作流
1. **定义蓝图**: 在`core`包的`types.ts`文件中维护`IModelManager`等接口。
2. **编写生成器脚本**: 使用`ts-morph`等库编写一个Node.js脚本该脚本能够读取并解析TypeScript接口的结构方法名、参数、返回值等
3. **自动生成样板代码**: 脚本遍历接口中的每个方法,并根据预设模板,自动生成`main.js`中的`ipcMain.handle`、`preload.js`中的`ipcRenderer`调用,以及`electron-proxy.ts`中的代理方法。
4. **一键更新**: 将此脚本集成到`package.json`中。未来新增/修改/删除一个接口方法时,开发者只需修改接口定义,然后运行一个命令(如`pnpm generate:ipc`所有相关的IPC代码都会被自动、无误地更新。
### 备选方案
社区中成熟的`tRPC`框架也提供了类似的思路,其核心就是"零代码生成"的类型安全API层。我们可以借鉴其思想甚至尝试将其集成到Electron的IPC机制中。
采用此方案后我们的开发流程将变得极为高效和安全彻底消除手动维护IPC调用可能带来的所有潜在错误。

View File

@@ -0,0 +1,173 @@
# 项目通用经验指南
本指南收录项目开发中的通用经验与最佳实践,快速解决常见问题,提升开发效率。
> **注意**: 功能特定的经验已归档到 `docs/archives/` 对应目录中。
## 📚 已归档的专项经验
- **模态框组件经验** → [106-template-management/modal-experience.md](../archives/106-template-management/modal-experience.md)
- **布局系统经验** → [108-layout-system/experience.md](../archives/108-layout-system/experience.md)
- **主题系统经验** → [109-theme-system/experience.md](../archives/109-theme-system/experience.md)
- **Composable架构经验** → [102-web-architecture-refactor/experience.md](../archives/102-web-architecture-refactor/experience.md)
## 🔧 通用开发规范
### API 集成
```typescript
// 统一 OpenAI 兼容格式
const config = {
baseURL: "https://api.provider.com/v1",
models: ["model-name"],
apiKey: import.meta.env.VITE_API_KEY // 必须使用 Vite 环境变量
};
```
**核心原则**
- 业务逻辑与API配置分离
- 只传递用户明确配置的参数,不设默认值
- 敏感信息通过环境变量管理
### 错误处理
```typescript
try {
await apiCall();
} catch (error) {
console.error('[Service Error]', error); // 开发日志
throw new Error('操作失败,请稍后重试'); // 用户友好提示
}
```
### 测试规范
```javascript
describe("功能测试", () => {
beforeEach(() => {
testId = `test-${Date.now()}`; // 唯一标识避免冲突
});
// LLM参数测试每个参数独立测试
it("should handle temperature parameter", async () => {
await modelManager.updateModel(configKey, {
llmParams: { temperature: 0.7 } // 只测试一个参数
});
});
});
```
**要点**
- 使用动态唯一标识符
- 每个LLM参数创建独立测试
- 覆盖异常场景
- 正确清理测试状态
### Vue 开发最佳实践
#### 多根组件的属性继承
**问题**当一个Vue组件有多个根节点时它无法自动继承父组件传递的非prop属性`class`),并会产生警告。
**方案**
1.`<script setup>` 中使用 `defineOptions({ inheritAttrs: false })` 禁用默认的属性继承行为
2. 在模板中,将 `v-bind="$attrs"` 手动绑定到你希望接收这些属性的**特定**根节点上
**示例**:
```html
<template>
<!-- $attrs 会将 class, id 等属性应用到此组件 -->
<OutputDisplayCore v-bind="$attrs" ... />
<OutputDisplayFullscreen ... />
</template>
<script setup>
defineOptions({
inheritAttrs: false,
});
</script>
```
## ⚡ 快速问题排查
### 布局问题
1. 检查 Flex 约束链是否完整
2. 确认 `min-h-0` 是否添加
3. 验证父容器是否为 `display: flex`
### 滚动问题
1. 检查是否有中间层错误的 `overflow` 属性
2. 确认高度约束是否从顶层正确传递
3. 验证滚动容器是否有正确的 `overflow-y: auto`
### API调用问题
1. 检查环境变量是否正确设置(`VITE_` 前缀)
2. 确认参数是否过度设置默认值
3. 验证错误处理是否用户友好
### 测试失败
1. 检查测试ID是否唯一
2. 确认测试后是否正确清理状态
3. 验证LLM参数测试是否独立
## 🔄 版本管理
### 版本同步
```json
// package.json
{
"scripts": {
"version": "pnpm run version:sync && git add -A"
}
}
```
**关键**:使用 `version` 钩子而非 `postversion`,确保同步文件包含在版本提交中。
### 模板管理
- **内置模板**:不可修改,不可导出
- **用户模板**可修改导入时生成新ID
- **导入规则**跳过与内置模板ID重复的模板
## 🚨 关键Bug修复模式
### 参数透明化
```typescript
// ❌ 错误:自动设置默认值
if (!config.temperature) config.temperature = 0.7;
// ✅ 正确:只使用用户配置的参数
const requestConfig = {
model: modelConfig.defaultModel,
messages: formattedMessages,
...userLlmParams // 只传递用户明确配置的参数
};
```
### 数据导入安全验证
```typescript
// 白名单验证 + 类型检查
for (const [key, value] of Object.entries(importData)) {
if (!ALLOWED_KEYS.includes(key)) {
console.warn(`跳过未知配置: ${key}`);
continue;
}
if (typeof value !== 'string') {
console.warn(`跳过无效类型 ${key}: ${typeof value}`);
continue;
}
await storage.setItem(key, value);
}
```
### 国际化(i18n)键值同步
**问题**`[intlify] Not found 'key' in 'locale' messages` 错误,通常由中英文语言包键值不同步引起。
**方案**:创建自动化脚本比较两个语言文件,列出差异。
## 📝 文档更新规范
遇到新问题或找到更好解决方案时,应及时更新此文档:
1. 在对应章节添加新经验
2. 更新代码示例
3. 记录修复时间和问题背景
4. 保持文档简洁性,避免过度详细的过程描述
---
**记住**:好的经验文档应该能让团队成员快速找到解决方案,而不是重新踩坑。

View File

@@ -0,0 +1,384 @@
# LLM高级参数配置指南
## 概述
`llmParams` 功能允许您为每个模型配置详细的参数以精确控制LLM的行为。本系统采用**智能参数分类**和**透明化传递**机制,确保参数配置的专业性和可靠性。
## 🔧 核心设计原则
### 1. 参数透明化 (2024.12.20 更新)
- **不设置默认值**: 系统不会自动添加任何默认值,避免用户误解
- **直接传递**: 用户配置什么参数就传递什么参数
- **SDK原生**: 依赖各LLM服务商的SDK默认行为
### 2. 智能参数分类
- **按提供商过滤**: UI自动根据模型类型显示相关参数
- **避免混淆**: OpenAI类型模型只显示OpenAI参数Gemini模型只显示Gemini参数
- **参数隔离**: 不同提供商的参数互不干扰
### 3. 扩展性保证
- **自定义参数**: 支持任意SDK兼容的自定义参数
- **未来兼容**: 新参数无需修改核心代码即可使用
- **类型保持**: 保持参数原始类型和结构
## 🚀 参数生效机制
### OpenAI兼容提供商 (OpenAI, DeepSeek, Zhipu, SiliconFlow, Custom)
#### 参数传递流程
```typescript
// 1. 分离特殊参数
const {
timeout, // 客户端配置参数
model, // 避免覆盖主模型配置
messages, // 避免覆盖主消息
...restLlmParams // 所有其他参数
} = modelConfig.llmParams || {};
// 2. 创建客户端实例
const openai = new OpenAI({
apiKey,
baseURL,
timeout: timeout || (isStream ? 90000 : 60000), // 仅timeout有特殊处理
maxRetries: isStream ? 2 : 3
});
// 3. 构建API请求 - 无默认值设置
const completionConfig = {
model: modelConfig.defaultModel,
messages: formattedMessages,
...restLlmParams // 直接传递所有其他参数
};
// 4. 发送请求
const response = await openai.chat.completions.create(completionConfig);
```
#### 支持的参数
| 参数名 | 类型 | 范围 | 说明 |
|--------|------|------|------|
| `timeout` | integer | ≥1000 | 请求超时(毫秒) - 客户端配置 |
| `temperature` | number | 0.0-2.0 | 控制输出随机性 |
| `max_tokens` | integer | ≥1 | 最大生成token数量 |
| `top_p` | number | 0.0-1.0 | 核心采样参数 |
| `presence_penalty` | number | -2.0-2.0 | 存在惩罚 |
| `frequency_penalty` | number | -2.0-2.0 | 频率惩罚 |
| `stop` | array | - | 停止序列 |
| `seed` | integer | - | 随机种子 |
| `stream` | boolean | - | 流式输出(系统自动处理) |
### Gemini提供商
#### 参数传递流程
```typescript
// 1. 分离已知参数和未知参数
const {
temperature,
maxOutputTokens,
topP,
topK,
candidateCount,
stopSequences,
...otherSafeParams // 未知参数也会传递
} = modelConfig.llmParams || {};
// 2. 构建生成配置 - 无默认值设置
const generationConfig = { ...otherSafeParams };
// 3. 仅添加用户明确配置的参数
if (temperature !== undefined) {
generationConfig.temperature = temperature;
}
if (maxOutputTokens !== undefined) {
generationConfig.maxOutputTokens = maxOutputTokens;
}
// ... 其他参数类似处理
// 4. 创建聊天会话
const chat = model.startChat({
history: formatHistory(messages),
...(Object.keys(generationConfig).length > 0 && { generationConfig })
});
```
#### 支持的参数
| 参数名 | 类型 | 范围 | 说明 |
|--------|------|------|------|
| `temperature` | number | 0.0-2.0 | 控制输出随机性 |
| `maxOutputTokens` | integer | ≥1 | 最大输出token数量 |
| `topP` | number | 0.0-1.0 | 核心采样参数 |
| `topK` | integer | ≥1 | Top-K采样 |
| `candidateCount` | integer | 1-8 | 候选响应数量 |
| `stopSequences` | array | - | 停止序列数组 |
## 🎯 UI智能参数管理
### 参数类型自动识别
系统会根据模型的`provider`字段自动显示相关参数:
```typescript
// 根据provider过滤参数定义
const availableParams = advancedParameterDefinitions.filter(def =>
def.appliesToProviders.includes(currentProvider) &&
!Object.keys(currentParams).includes(def.name)
);
```
### 提供商映射关系
```typescript
const providerMapping = {
// OpenAI兼容类型
'openai': ['temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty', 'timeout'],
'deepseek': ['temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty', 'timeout'],
'zhipu': ['temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty', 'timeout'],
'siliconflow': ['temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty', 'timeout'],
'custom': ['temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty', 'timeout'],
// Gemini类型
'gemini': ['temperature', 'topP', 'maxOutputTokens', 'topK', 'candidateCount', 'stopSequences']
};
```
### UI显示增强
- 显示当前提供商类型
- 显示可选参数数量
- 彩色状态指示
- 自动过滤已配置参数
## 📋 配置示例
### OpenAI模型配置
```json
{
"name": "OpenAI GPT-4",
"provider": "openai",
"llmParams": {
"temperature": 0.3, // 低随机性,更确定的输出
"max_tokens": 4096, // 限制输出长度
"top_p": 0.8, // 核心采样
"presence_penalty": 0.1, // 鼓励新话题
"timeout": 90000 // 90秒超时
}
}
```
### DeepSeek模型配置
```json
{
"name": "DeepSeek Coder V3",
"provider": "deepseek",
"llmParams": {
"temperature": 0.1, // 代码生成需要低随机性
"max_tokens": 8192, // 较长的代码输出
"top_p": 0.95, // 平衡多样性和质量
"timeout": 120000 // 代码生成可能需要更长时间
}
}
```
### Gemini模型配置
```json
{
"name": "Gemini Pro",
"provider": "gemini",
"llmParams": {
"temperature": 0.8, // 创意任务高随机性
"maxOutputTokens": 2048, // 适中输出长度
"topP": 0.95, // 核心采样
"topK": 40, // Top-K采样
"candidateCount": 1, // 单个响应
"stopSequences": ["END", "STOP"] // 自定义停止词
}
}
```
### 自定义模型配置
```json
{
"name": "Custom LLaMA",
"provider": "custom",
"llmParams": {
"temperature": 0.7,
"max_tokens": 4096,
// 自定义参数示例
"repetition_penalty": 1.1,
"do_sample": true,
"pad_token_id": 0,
"eos_token_id": 2
}
}
```
## 🔍 验证与调试
### 参数验证API
```typescript
import { validateLLMParams } from '@prompt-optimizer/core';
const validation = validateLLMParams(llmParams, provider);
if (!validation.isValid) {
console.error('参数验证失败:', validation.errors);
validation.errors.forEach(error => {
console.error(`- ${error.parameterName}: ${error.message}`);
});
}
if (validation.warnings.length > 0) {
console.warn('参数警告:', validation.warnings);
validation.warnings.forEach(warning => {
console.warn(`- ${warning.parameterName}: ${warning.message}`);
});
}
```
### 测试每个参数
系统为每个参数提供独立的测试用例:
```typescript
// 测试temperature参数
await testParameter('temperature', 0.3, provider);
// 测试max_tokens参数
await testParameter('max_tokens', 100, provider);
// 测试组合参数
await testParameters({
temperature: 0.6,
max_tokens: 150,
top_p: 0.9
}, provider);
```
## ⚡ 最佳实践
### 1. 参数选择策略
```typescript
// 代码生成任务
const codingParams = {
temperature: 0.1, // 低随机性
max_tokens: 8192, // 长输出
top_p: 0.95 // 高质量采样
};
// 创意写作任务
const creativeParams = {
temperature: 0.8, // 高随机性
max_tokens: 2048, // 适中输出
top_p: 0.9, // 平衡采样
presence_penalty: 0.3 // 鼓励新想法
};
// 问答任务
const qaParams = {
temperature: 0.3, // 中等随机性
max_tokens: 1024, // 简洁回答
frequency_penalty: 0.1 // 避免重复
};
```
### 2. 渐进式调优
```typescript
// 第一步:基础配置
let params = {
temperature: 0.7
};
// 第二步:添加输出控制
params = {
...params,
max_tokens: 2048,
top_p: 0.9
};
// 第三步:精细调整
params = {
...params,
presence_penalty: 0.1,
frequency_penalty: 0.1
};
```
### 3. 性能优化
```typescript
// 快速响应场景
const fastParams = {
max_tokens: 512, // 限制输出长度
timeout: 30000 // 较短超时
};
// 高质量场景
const qualityParams = {
temperature: 0.2, // 低随机性
top_p: 0.8, // 精确采样
timeout: 120000 // 较长超时
};
```
## 🛠️ 故障排除
### 常见问题诊断
1. **参数不生效**
```typescript
// 检查参数名是否正确
console.log('支持的参数:', advancedParameterDefinitions
.filter(def => def.appliesToProviders.includes(provider))
.map(def => def.name));
```
2. **类型错误**
```typescript
// 确保参数类型正确
const temperature = parseFloat(userInput); // 确保是number
const maxTokens = parseInt(userInput, 10); // 确保是integer
```
3. **范围错误**
```typescript
// 检查参数范围
if (temperature < 0 || temperature > 2) {
throw new Error('temperature必须在0-2之间');
}
```
### 调试工具
1. **启用详细日志**
```typescript
// 在modelManager中启用调试
const debugMode = process.env.NODE_ENV === 'development';
if (debugMode) {
console.log('LLM参数配置:', llmParams);
console.log('当前provider:', provider);
}
```
2. **参数传递跟踪**
```typescript
// 查看实际传递的参数
console.log('传递给SDK的参数:', {
...completionConfig,
provider,
timestamp: new Date().toISOString()
});
```
## 📝 更新日志
### 2024.12.20 - 参数透明化更新
- ✅ 移除所有自动设置的默认值
- ✅ 改进参数类型自动过滤
- ✅ 优化UI显示和标签
- ✅ 增强测试覆盖率
- ✅ 添加参数组合测试
- ✅ 完善故障排除指南
### 核心改进
- **透明化原则**: 只传递用户明确配置的参数
- **智能分类**: 根据provider自动显示相关参数
- **UI优化**: 移除标签中的冗余提供商标识
- **测试完善**: 为每个参数添加独立测试用例

View File

@@ -0,0 +1,191 @@
# 项目结构文档
> **注意:** 本文档专注于项目的文件和目录结构。关于技术栈详情和实现流程,请参考 [技术文档](./technical-documentation.md)。
## 1. 项目整体架构
### 1.1 根目录结构
```
prompt-optimizer/
├── packages/ # 项目包
│ ├── core/ # 核心功能包
│ │ ├── src/ # 核心源代码
│ │ ├── tests/ # 核心包测试
│ │ └── package.json # 核心包配置
│ ├── web/ # Web版本
│ │ ├── src/ # Web源代码
│ │ ├── tests/ # Web测试
│ │ └── package.json # Web包配置
│ └── extension/ # Chrome插件
├── docs/ # 项目文档
├── tools/ # 工具脚本
└── ...配置文件
```
### 1.2 配置文件
- `pnpm-workspace.yaml` - 工作区配置
- `.env.example` - 环境变量示例
- `package.json` - 项目配置
- `.vscode/` - VSCode配置目录
- `.cursorrules` - Cursor IDE配置
- `.gitignore` - Git忽略配置
### 1.3 工作区文件
- `README.md` - 项目说明文档
- `scratchpad.md` - 开发笔记和任务规划已迁移到docs/workspace/
- `experience.md` - 项目经验总结已迁移到docs/workspace/
### 1.4 文档目录 (docs/)
- `README.md` - 文档索引
- `development-guidelines.md` - 开发指南
- `project-status.md` - 项目状态
- `project-structure.md` - 项目结构
- `technical-documentation.md` - 技术文档
- `prd.md` - 产品需求文档
- `CHANGELOG.md` - 更新日志
## 2. 核心包结构 (packages/core)
### 2.1 源代码目录 (packages/core/src/)
```
src/
├── services/ # 核心服务
│ ├── llm/ # LLM服务
│ │ ├── service.ts # LLM服务实现
│ │ ├── types.ts # 类型定义
│ │ └── errors.ts # 错误定义
│ ├── model/ # 模型管理
│ │ ├── manager.ts # 模型管理器
│ │ ├── types.ts # 类型定义
│ │ └── defaults.ts# 默认配置
│ ├── prompt/ # 提示词服务
│ │ ├── service.ts # 提示词服务实现
│ │ ├── types.ts # 类型定义
│ │ └── errors.ts # 错误定义
│ ├── template/ # 模板服务
│ │ ├── manager.ts # 模板管理器
│ │ ├── types.ts # 类型定义
│ └── history/ # 历史记录服务
│ ├── manager.ts # 历史管理器
│ └── types.ts # 类型定义
├── types/ # 公共类型定义
└── utils/ # 工具函数
```
### 2.2 API目录 (src/api/)
- `api/llm.js` - LLM API调用封装
### 2.3 配置目录 (packages/core/config/)
- `models.js` - LLM模型配置
- `prompts.js` - 提示词模板配置
### 2.4 测试目录 (packages/core/tests/)
```
tests/
├── unit/ # 单元测试
│ └── services/ # 服务测试
│ ├── llm/ # LLM服务测试
│ ├── model/ # 模型管理测试
│ └── prompt/ # 提示词服务测试
└── integration/ # 集成测试
└── services/ # 服务集成测试
```
### 2.5 核心包配置
- `package.json` - 核心包配置
- `tsconfig.json` - TypeScript配置
- `vitest.config.ts` - 测试配置
## 3. Web包结构 (packages/web)
### 3.1 源代码目录 (packages/web/src/)
```
src/
├── components/ # Vue组件
│ ├── PromptPanel.vue # 提示词面板
│ ├── ModelManager.vue # 模型管理器
│ ├── TemplateManager.vue# 模板管理器
│ ├── InputPanel.vue # 输入面板
│ └── OutputPanel.vue # 输出面板
├── composables/ # Vue组合式函数
├── services/ # 业务逻辑
│ ├── llm/ # LLM服务
│ ├── model/ # 模型配置
│ ├── prompt/ # 提示词服务
│ ├── promptManager.js # 提示词管理
│ └── themeManager.js # 主题管理
├── assets/ # 静态资源
│ ├── images/ # 图片资源
│ └── styles/ # 样式资源
├── prompts/ # 提示词模板
├── App.vue # 根组件
└── main.ts # 入口文件
```
### 3.2 组件目录详情 (packages/web/src/components/)
- `PromptPanel.vue` - 提示词输入和优化面板
- `InputPanel.vue` - 输入面板组件
- `OutputPanel.vue` - 输出面板组件
- `ModelConfig.vue` - 模型配置组件
- `ThemeToggle.vue` - 主题切换组件
- `LoadingSpinner.vue` - 加载动画组件
### 3.3 测试目录 (packages/web/tests/)
```
tests/
├── unit/ # 单元测试
│ ├── components/ # 组件测试
│ └── services/ # 服务测试
└── integration/ # 集成测试
└── services/ # 服务集成测试
```
### 3.4 Web包配置
- `package.json` - Web包配置
- `vite.config.ts` - Vite配置
- `tailwind.config.js` - TailwindCSS配置
- `.env.local` - 本地环境变量
- `postcss.config.js` - PostCSS配置
- `index.html` - 项目入口HTML文件
## 4. 扩展包结构 (packages/extension)
### 4.1 源代码目录 (packages/extension/src/)
```
src/
├── popup/ # 弹出窗口界面
├── background/ # 后台脚本
├── content/ # 内容脚本
└── manifest.json # 扩展配置文件
```
### 4.2 扩展包配置
- `package.json` - 扩展包配置
- `vite.config.ts` - 构建配置
## 5. 依赖关系
### 5.1 核心包依赖 (@prompt-optimizer/core)
```
@prompt-optimizer/core
├── @openai/openai ^4.83.0 # OpenAI SDK
├── @google/generative-ai ^0.21.0 # Google Generative AI SDK
└── uuid ^11.0.5 # UUID生成
```
### 5.2 Web包依赖 (@prompt-optimizer/web)
```
@prompt-optimizer/web
├── @prompt-optimizer/core # 依赖核心包
├── vue ^3.5.x # Vue框架
├── pinia ^2.1.x # 状态管理
└── tailwindcss ^3.4.1 # 样式框架
```
### 5.3 扩展包依赖 (@prompt-optimizer/extension)
```
@prompt-optimizer/extension
├── @prompt-optimizer/core # 依赖核心包
├── @prompt-optimizer/ui # 依赖UI组件包
└── vue ^3.5.x # Vue框架
```

View File

@@ -0,0 +1,546 @@
# 技术开发指南
> **注意:** 本文档整合了原有的开发指南和技术文档,提供完整的技术栈说明和开发规范。
## 1. 项目技术架构
### 1.1 整体架构
- Monorepo结构
- packages/core - 核心功能包
- packages/web - Web应用
- packages/extension - Chrome扩展
- packages/ui - 共享UI组件
- 包间依赖管理
- 清晰的依赖关系
- 版本一致性
- 最小化重复代码
- 工程化工具
- pnpm workspace
- 多包管理
- 统一版本控制
### 1.2 技术栈概览
#### 1.2.1 核心包 (@prompt-optimizer/core)
- TypeScript 5.3.x
- 类型系统
- 接口定义
- 模块化
- 原生SDK集成
- OpenAI SDK ^4.83.0
- Google Generative AI SDK ^0.21.0
- 模型管理
- 提示词处理
- 流式响应
- 工具库
- uuid ^11.0.5
- zod ^3.22.4
- 错误处理
- 类型定义
#### 1.2.2 Web包 (@prompt-optimizer/web)
- Vue 3.5.x
- Composition API
- Script Setup
- 响应式系统
- 组件生态
- Vite 6.0.x
- 快速开发服务器
- 优化的构建
- 插件系统
- HMR支持
#### 1.2.3 UI框架和样式
- TailwindCSS 3.4.x
- 实用优先
- 响应式设计
- 深色模式支持
- 动画系统
- Vue Transitions
- 页面过渡动画
- 组件切换效果
- 列表动画
- Element Plus 2.9.x
- 组件库
- 主题支持
- 响应式组件
#### 1.2.4 状态管理
- Vue Reactivity
- ref/reactive
- computed
- watch
- watchEffect
- LocalStorage
- 配置持久化
- 历史记录存储
- 模板管理
- 加密存储
- Pinia 2.1.x
- 状态管理
- 持久化
- 插件支持
#### 1.2.5 安全性
- WebCrypto API
- API密钥加密
- 安全存储
- 密钥轮换
- XSS防护
- 输入验证
- 内容过滤
- 安全编码
- CORS配置
- API访问控制
- 安全头部
- CSP策略
#### 1.2.6 开发工具
- TypeScript 5.3.x
- 类型检查
- 代码提示
- 接口定义
- ESLint 8.56.x
- 代码规范
- 自动修复
- TypeScript支持
- Prettier 3.2.x
- 代码格式化
- 统一风格
- 编辑器集成
#### 1.2.7 测试框架
- Vitest 3.0.x
- 单元测试
- 集成测试
- 快照测试
- 覆盖率报告
- Vue Test Utils 2.4.x
- 组件测试
- 行为模拟
- 事件测试
- Playwright 1.41.x
- E2E测试
- 跨浏览器测试
- 视觉回归测试
### 1.3 代码组织
- 模块化设计
- 按功能划分模块
- 单一职责原则
- 关注点分离
- 统一目录结构
- src/ - 源代码
- tests/ - 测试代码
- types/ - 类型定义
- config/ - 配置文件
## 2. 核心包开发规范
### 2.1 服务实现规范
- 接口一致性
- 所有服务必须实现统一接口
- 方法命名保持一致
- 错误处理遵循统一模式
- 返回值类型一致
- 错误处理
- 使用统一的错误类型
- 错误信息应包含上下文
- 实现错误恢复机制
- 提供用户友好的错误信息
### 2.2 SDK集成规范
- 原生SDK集成
- 直接使用官方SDK
- 避免不必要的抽象层
- 保持版本更新
- 遵循官方最佳实践
- 错误映射
- SDK特定错误映射到统一错误类型
- 保留原始错误信息
- 实现重试机制
- 提供降级方案
### 2.3 类型定义规范
- 类型安全性
- 使用精确的类型定义
- 避免any类型
- 使用联合类型表示可能的值
- 为复杂对象定义接口
- 类型导出
- 在index.ts中集中导出类型
- 按模块组织类型定义
- 使用命名空间避免冲突
- 提供类型文档注释
### 2.4 测试规范
- 单元测试
- 测试覆盖率目标>80%
- 测试边界条件
- 模拟外部依赖
- 验证错误处理
- 集成测试
- 测试服务间交互
- 验证端到端流程
- 测试性能和并发
- 模拟真实环境
## 3. 前端开发规范
### 3.1 项目架构
- 推荐目录结构
```
src/
├── components/ # UI组件
├── composables/ # 组合式函数
├── views/ # 页面组件
├── services/ # 服务
├── stores/ # Pinia状态
├── assets/ # 静态资源
├── utils/ # 工具函数
├── types/ # 类型定义
├── App.vue # 根组件
└── main.ts # 入口文件
```
- 命名规范
- 组件文件PascalCase.vue
- 工具函数文件camelCase.ts
- 类型定义文件camelCase.types.ts
- 组合式函数useXxx.ts
### 3.2 服务使用规范
- 核心服务集成
- 使用统一的服务访问模式
- 实现服务单例模式
- 处理服务初始化
- 管理服务状态
- 错误处理
- 使用统一的错误处理机制
- 提供用户友好的错误提示
- 实现错误恢复
- 记录错误日志
### 3.3 组件开发规范
- Vue组件模板
- 使用<script setup>语法
- 明确定义props和emits
- 使用TypeScript类型
- 遵循单一职责原则
- 组件设计原则
- 组件应该是可复用的
- 组件应该是可测试的
- 组件应该是可维护的
- 组件应该是可扩展的
### 3.4 类型系统
- Vue组件类型
- 为props定义明确类型
- 为emits定义事件类型
- 为ref和reactive定义类型
- 使用泛型增强类型安全
- 通用工具类型
- 创建可复用的工具类型
- 使用TypeScript内置工具类型
- 为复杂数据结构定义类型
- 避免类型断言
### 3.5 状态管理
- Pinia存储
- 按功能模块组织store
- 使用组合式API风格
- 实现持久化
- 处理异步操作
- 组合式API状态
- 使用composables封装状态逻辑
- 实现状态共享
- 处理生命周期
- 管理副作用
### 3.6 性能优化
- 动态导入
- 使用路由懒加载
- 组件按需加载
- 第三方库按需导入
- 代码分割
- 渲染优化
- 使用虚拟列表
- 避免不必要的渲染
- 使用计算属性缓存
- 优化大型列表
### 3.7 测试规范
- 组件测试
- 测试组件渲染
- 测试用户交互
- 测试props和emits
- 测试边界条件
- 服务测试
- 模拟外部依赖
- 测试异步操作
- 测试错误处理
- 验证状态变化
## 4. 应用流程
### 4.1 核心服务初始化
1. **核心服务加载顺序**
- 导入核心服务modelManager, templateManager, historyManager
- 加载模型配置
- 加载模板配置
- 加载历史记录
2. **服务实例创建流程**
- 创建LLM服务实例
- 创建提示词服务实例
- 注册事件处理器
- 初始化服务状态
### 4.2 Web应用初始化
1. **应用配置加载**
- 环境变量加载
- 主题设置初始化
- Vue应用配置
2. **服务状态同步**
- 模型状态初始化
- 模板数据加载
- 历史记录同步
### 4.3 提示词优化流程
1. **用户输入阶段**
- 输入验证流程
- 错误处理机制
- 输入清理和预处理
2. **优化处理阶段**
- 使用原生SDK处理请求
- 调用LLM服务进行优化
- 流式响应处理
- 错误处理与重试
3. **结果处理阶段**
- 流式响应UI更新
- 结果存储到历史记录
- 错误恢复和降级处理
### 4.4 模型管理流程
1. **模型配置管理**
- 模型配置更新: 用户可以更新模型的名称、基础URL、API密钥、可用模型列表、默认模型以及是否启用。
- **高级LLM参数 (`llmParams`)**:
- `ModelConfig` 接口包含一个 `llmParams?: Record<string, any>;` 字段。
- 此字段允许用户为每个模型配置提供一个灵活的键值对映射用于指定特定于该LLM提供商SDK的参数。
- 用户可以添加其LLM SDK支持的任何参数。
- **示例**:
- **OpenAI/OpenAI兼容API (如 DeepSeek, Zhipu):**
```json
"llmParams": {
"temperature": 0.7,
"max_tokens": 4096,
"timeout": 60000, // 用于OpenAI客户端的请求超时 (毫秒)
"top_p": 0.9,
"frequency_penalty": 0.5
// ... 其他OpenAI支持的参数
}
```
- **Gemini:**
```json
"llmParams": {
"temperature": 0.8,
"maxOutputTokens": 2048, // 注意: Gemini使用maxOutputTokens
"topP": 0.95,
"topK": 40
// ... 其他Gemini支持的参数
}
```
- **`LLMService` 如何处理 `llmParams`**:
- 对于OpenAI兼容的API, `timeout` 值如果提供用于配置OpenAI JavaScript SDK客户端实例的超时设置。其余参数如 `temperature`, `max_tokens`, `top_p` 等)会直接传递给 `chat.completions.create()` 方法。
- 对于Gemini, `temperature`, `maxOutputTokens`, `topP`, `topK` 等参数会包含在传递给 `model.startChat()` 的 `generationConfig` 对象中。
- 未被服务明确处理的参数(即非 `timeout` for OpenAI, 或非已知Gemini参数通常会被安全地传递给相应SDK的请求中如果SDK支持它们。
- 连接测试: 验证API密钥和基础URL是否正确以及模型是否可用。
- 配置验证: 确保所有必填字段都已填写,并且格式正确。`llmParams` 字段(如果提供)必须是一个对象。
- 错误处理: 在配置不正确或连接失败时提供明确的错误信息。
2. **API密钥管理**
- 密钥设置与加密
- 密钥验证
- 安全存储
- 错误处理
### 4.5 模板管理流程
1. **模板操作流程**
- 模板保存
- 模板验证
- 模板分类管理
- 错误处理
2. **模板应用流程**
- 模板获取
- 模板应用
- 数据验证
- 错误处理
### 4.6 历史记录管理
1. **记录保存流程**
- 添加记录
- 数据同步
- 自动清理
- 错误处理
2. **记录操作流程**
- 获取记录
- 过滤记录
- 删除记录
- 错误处理
### 4.7 错误处理流程
1. **API错误处理策略**
- 可重试错误识别
- 退避重试机制
- 错误上报
- 用户通知
- 降级处理
2. **验证错误处理**
- 字段验证
- UI更新
- 焦点处理
- 错误提示
3. **全局错误处理**
- 错误分类
- 错误恢复
- 错误上报
- 用户反馈
## 5. 代码审查清单
### 5.1 通用审查项
- 代码质量
- [ ] 遵循约定的代码风格
- [ ] 没有未使用的变量或导入
- [ ] 适当的注释和文档
- [ ] 避免重复代码
- 安全性
- [ ] 输入验证
- [ ] 敏感信息保护
- [ ] API密钥安全存储
- [ ] 防止XSS攻击
- 性能
- [ ] 避免不必要的计算
- [ ] 大型数据集的性能处理
- [ ] 缓存计算结果
### 5.2 前端审查项
- 组件设计
- [ ] 组件职责单一
- [ ] 属性和事件定义清晰
- [ ] 状态管理合理
- [ ] 错误处理完善
- UI/UX
- [ ] 响应式设计
- [ ] 无障碍性支持
- [ ] 良好的错误反馈
- [ ] 加载状态处理
### 5.3 核心包审查项
- API设计
- [ ] 接口一致性
- [ ] 错误处理标准化
- [ ] 类型定义完整
- [ ] 文档注释
- 服务实现
- [ ] 单一职责原则
- [ ] 适当的抽象级别
- [ ] 测试覆盖率
- [ ] 错误恢复机制
## 6. 开发环境要求
### 6.1 开发环境
- Node.js >= 18.0.0
- pnpm >= 8.15.0
- VS Code
- Volar 1.8.x
- ESLint
- Prettier
- Cursor
- GitLens
- Tailwind CSS IntelliSense
### 6.2 浏览器支持
- Chrome >= 90
- Firefox >= 90
- Safari >= 14
- Edge >= 90
- 移动端浏览器
- iOS Safari >= 14
- Android Chrome >= 90
## 跨域代理解决方案
为了解决在纯前端应用中调用第三方LLM API时可能遇到的跨域问题我们实现了一个基于Vercel Edge Runtime的代理解决方案。
### 代理架构
1. **API代理**:用于处理普通请求
- 路径:`/api/proxy`
- 功能转发普通HTTP请求处理CORS头
2. **流式代理**:用于处理流式请求
- 路径:`/api/stream`
- 功能:转发流式响应,保持连接直到流结束
### 工作原理
1. 在生产环境中非localhost系统会自动检测是否需要使用代理
2. 所有API请求包括OpenAI都可以使用代理通过模型配置中的`useVercelProxy`选项控制
3. 代理会保留原始请求的所有头信息和请求体
4. 代理会添加必要的CORS头允许浏览器接收响应
### 代码实现
核心代理逻辑位于:
- `/api/proxy.js`:处理普通请求
- `/api/stream.js`:处理流式请求
环境检测逻辑位于:
- `packages/core/src/utils/environment.ts`
### 使用方式
对于开发者来说这个功能是透明的不需要额外配置。系统会自动检测Vercel环境并在模型配置中提供代理选项。
在模型配置界面中当检测到Vercel环境时会显示"使用Vercel代理"的选项。您可以为每个模型单独配置是否启用代理功能。
### 安全考虑
1. 代理仅转发请求,不存储任何数据
2. API密钥仍然由客户端直接发送不经过中间服务器处理
3. 所有请求都通过HTTPS加密传输
### 限制
1. Vercel Edge Functions有30秒的超时限制
2. 有每月带宽和请求数量限制
3. 首次请求可能有冷启动延迟
最后更新2025-01-06

119
docs/developer/todo.md Normal file
View File

@@ -0,0 +1,119 @@
# 开发任务清单
按功能模块和优先级组织的开发任务列表。
## 🚨 高优先级任务
### 组件标准化重构
**目标**: 统一所有模态框/弹窗类组件的行为和API
#### 1. 标准化Prop为 `modelValue`
- [ ] `DataManager.vue` - 将 `show` prop 改为 `modelValue`
- [ ] `HistoryDrawer.vue` - 将 `show` prop 改为 `modelValue`
- [ ] `ModelManager.vue` - 将 `show` prop 改为 `modelValue`
- [ ] `TemplateManager.vue` - 将 `show` prop 改为 `modelValue`
- [ ] `App.vue` - 更新所有组件调用,将 `v-model:show` 改为 `v-model`
#### 2. 补全 `Escape` 键支持
- [ ] `ModelManager.vue` - 添加ESC键关闭功能
- [ ] `TemplateManager.vue` - 添加ESC键关闭功能
- [ ] `Modal.vue` - 添加ESC键关闭功能基础组件
#### 3. 修复关键Bug
- [ ] `ModelManager.vue` - 添加 `v-if="show"` 指令修复启动显示问题
- [ ] 解决 TypeScript 类型错误
- [ ] 为相关对象创建明确的 TypeScript 接口
### Web架构完善
**目标**: 完成Composable架构重构的剩余工作
- [ ] 解决 App.vue 中的类型错误
- [ ] 深入研究 `DataManager` 类型定义和实现
- [ ] 调整 `AppServices` 接口或服务实现
- [ ] 添加错误处理UI界面
## 🔧 中优先级任务
### 文档完善
- [ ] 创建Web版用户指南
- [ ] 创建开发者快速开始指南
- [ ] 创建常见问题解答文档
- [ ] 创建核心API文档
- [ ] 创建架构概览文档
### 桌面端架构优化
- [ ] 实施高层服务代理IPC模型重构
- [ ] 清理 `core` 包中的 Electron 特定逻辑
- [ ] 改造 `main.js` 为服务提供者
- [ ] 实现主进程存储方案
- [ ] 重构 IPC 通信协议
### CSS兼容性改进
- [ ] 添加标准 `line-clamp` 属性
- [ ] 提高浏览器兼容性
- [ ] 优化主题系统样式
## 📋 低优先级任务
### 长期重构计划
- [ ] 创建可复用的 `BaseModal.vue` 组件
- [ ] 将通用模态框逻辑抽象到基础组件
- [ ] 通过插槽方式实现内容定制
- [ ] 创建贡献指南
- [ ] 创建设计模式文档
### 测试和质量
- [ ] 创建测试指南
- [ ] 完善单元测试覆盖率
- [ ] 创建发布流程文档
- [ ] 创建代码规范文档
### 性能优化
- [ ] 优化应用启动时间
- [ ] 减少包体积
- [ ] 添加启动画面
- [ ] 优化错误处理和用户提示
## 🔄 定期维护任务
### 每周
- [ ] 检查workspace中的临时文档及时转移重要内容
- [ ] 更新项目状态文档
- [ ] 清理过期的临时文档
### 每月
- [ ] 审查所有文档的时效性
- [ ] 更新归档索引
- [ ] 评估任务优先级调整
## 📊 任务状态追踪
### 组件标准化重构进度
- **总任务数**: 11
- **已完成**: 0
- **进行中**: 11
- **完成率**: 0%
### Web架构完善进度
- **总任务数**: 4
- **已完成**: 0
- **进行中**: 4
- **完成率**: 0%
## 🎯 下一步行动
### 本周重点
1. 完成 `ModelManager.vue``v-if="show"` 修复
2. 开始组件标准化重构的第一批任务
3. 解决 App.vue 类型错误
### 本月目标
1. 完成组件标准化重构的核心任务
2. 完善Web架构的剩余工作
3. 创建基础的用户和开发者文档
---
**创建时间**: 2025-07-01
**最后更新**: 2025-07-01
**维护者**: AI Assistant

View File

@@ -0,0 +1,53 @@
# 故障排查指南
这里包含了开发过程中常见问题的排查清单和解决方案。
## 📋 排查清单
### 通用问题
- [通用排查清单](./general-checklist.md) - UI模块文件级排查清单按具体文件组织的问题排查指南
### 特定功能问题
- 模板管理问题 - 参见归档文档 [106-template-management](../../archives/106-template-management/troubleshooting.md)
## 🔍 问题分类
### 应用启动问题
- 应用无法启动
- 白屏问题
- 服务初始化失败
### 组件渲染问题
- 模态框显示异常
- 组件状态错误
- 响应式数据问题
### 异步操作问题
- API调用失败
- 异步方法缺少await
- 时序问题
### 架构相关问题
- 依赖注入问题
- Composable使用错误
- 服务层问题
## 📝 使用说明
1. **定位问题类型**:根据问题现象确定属于哪个分类
2. **查看对应清单**:找到相关的排查清单文档
3. **按步骤排查**:按照清单逐项检查
4. **记录解决方案**:解决问题后更新相关文档
## 🔄 文档维护
- 每次解决新问题后,考虑更新相关排查清单
- 定期审查排查清单的有效性
- 将常见问题的解决方案添加到清单中
## 📞 获取帮助
如果排查清单无法解决问题:
1. 查看相关的归档文档中的经验总结
2. 在项目仓库提交Issue
3. 联系项目团队

View File

@@ -0,0 +1,134 @@
# UI 模块文件级排查清单 (v3)
本文档将常见问题排查清单以**具体文件为单位**进行组织和索引。当遇到问题时,可直接定位到相关文件,并检查下文中列出的所有关键点。每次团队成员根据此清单解决问题后,都应考虑更新此文件,以保证其时效性。
---
## Part 1: 应用入口与状态组装
### 📍 `packages/web/src/App.vue`
这是组装所有核心 Composable 和 UI 组件的主入口,是检查问题的起点。
- **[x] 顶层 Composable 调用**: 确认所有 `use...()` hook 都在 `<script setup>` 的顶层被调用。它们绝不能存在于 `async` 函数、`.then()` 回调或任何其他异步逻辑内部。
- **[x] `toRef` 适配器**: 检查所有传递给子 Composable 的 props。如果一个 `reactive` 对象的属性(如 `optimizerState.currentChainId`)被传递给一个期望 `Ref` 类型参数的 Composable请确保它被 `toRef(optimizerState, 'currentChainId')` 正确包装。
---
## Part 2: Composable 架构与逻辑
### 📍 `packages/ui/src/composables/useAppInitializer.ts`
- **[x] 依赖注入完整性**: 确认所有被应用依赖的服务(如 `templateLanguageService`)都已在 `services` 对象中正确注册并返回。
### 📍 `packages/ui/src/composables/usePromptOptimizer.ts`
- **[x] 返回 `reactive`**: 确认 `return` 语句返回的是单一的 `reactive` 对象。
- **[x] `nextTick` 防护**: 在 `handleOptimizePrompt` 等函数中,确认在 `await` 异步服务**之前**,已同步完成状态清理(如 `optimizedPrompt.value = ''`),并紧跟 `await nextTick()`
### 📍 `packages/ui/src/composables/useModelManager.ts`
- **[x] 返回 `reactive`**: 确认 `return` 语句返回的是单一的 `reactive` 对象。
- **[x] `watch` 内部依赖**: 确认其内部通过 `watch` 监听 `services` 的就绪状态来执行初始化逻辑。
### 📍 `packages/ui/src/composables/useTemplateManager.ts`
- **[x] 返回 `reactive`**: 确认 `return` 语句返回的是单一的 `reactive` 对象。
- **[x] `watch` 内部依赖**: 确认其内部通过 `watch` 监听 `services` 的就绪状态。
### 📍 `packages/ui/src/composables/useHistoryManager.ts`
- **[x] 返回 `reactive`**: 确认 `return` 语句返回的是单一的 `reactive` 对象。
- **[x] `watch` 内部依赖**: 确认其内部通过 `watch` 监听 `services` 的就绪状态。
### 📍 `packages/ui/src/composables/usePromptHistory.ts`
- **[x] `watch` 内部依赖**: 确认其内部通过 `watch` 监听 `services` 的就绪状态。
- **[x] `Ref` 参数类型**: 确认其接收的 `currentChainId` 等参数都是 `Ref` 类型。
### 📍 `packages/ui/src/composables/usePromptTester.ts`
- **[x] 返回 `reactive`**: 确认 `return` 语句返回的是单一的 `reactive` 对象。
- **[x] `watch` 内部依赖**: 确认其内部通过 `watch` 监听 `services` 的就绪状态。
### 📍 `packages/ui/src/composables/useStorage.ts`
- **[x] `watch` 内部依赖**: 确认其内部通过 `watch` 监听 `services` 的就绪状态,以避免 `Invalid watch source` 警告。
---
## Part 3: UI 组件实现
### 📍 `packages/ui/src/components/MainLayout.vue`
- **[x] Flexbox 父容器**: 检查根元素是否为 `flex` 容器,为子元素(如 `InputPanel`)的 `flex-1` 提供约束。
### 📍 `packages/ui/src/components/InputPanel.vue`
- **[x] `min-h-0` 约束**: 检查内部需要滚动的 `textarea` 区域,其父级容器链条上是否应用了 `flex-1 min-h-0` 以实现正确的空间分配。
### 📍 `packages/ui/src/components/OutputPanel.vue`
- **[x] `min-h-0` 约束**: 同 `InputPanel.vue`,检查滚动区域的 Flex 约束。
### 📍 `packages/ui/src/components/TestPanel.vue`
- **[x] `min-h-0` 约束**: 特别注意检查此组件,因其布局复杂,需要确保所有 `flex` 子项都有正确的 `min-h-0` 约束。
### 📍 `packages/ui/src/components/Modal.vue`
- **[x] `v-if` 根元素**: 确认组件的根 DOM 元素上有 `v-if="modelValue"` 指令。
- **[x] `v-model` 支持**: 确认 `close()` 方法中调用了 `emit('update:modelValue', false)`
- **[x] 安全背景点击**: 确认背景遮罩层的 `@click` 事件处理函数中使用了 `event.target === event.currentTarget` 判断。
### 📍 `packages/ui/src/components/FullscreenDialog.vue`
- **[x] `v-if` / `v-model`**: 同 `Modal.vue`
- **[x] 安全背景点击**: 同 `Modal.vue`
### 📍 `packages/ui/src/components/TemplateManager.vue`
- **[x] `v-if` / `v-model`**: 同 `Modal.vue`
- **[x] 安全背景点击**: 同 `Modal.vue`
### 📍 `packages/ui/src/components/ModelManager.vue`
- **[x] `v-if` / `v-model`**: 同 `Modal.vue`
- **[x] 安全背景点击**: 同 `Modal.vue`
### 📍 `packages/ui/src/components/HistoryDrawer.vue`
- **[x] `v-if` / `v-model`**: 检查 `v-if="show"``emit('update:show', false)`
- **[x] 安全背景点击**: 同 `Modal.vue`
### 📍 `packages/ui/src/components/OutputDisplayCore.vue`
- **[x] 实时 `emit`**: 检查 `<script setup>` 中是否存在一个 `watch`,它正在监听本地的编辑状态,并在内容变化时**立即**通过 `emit('update:content', ...)` 通知父组件。
### 📍 `packages/ui/src/components/MarkdownRenderer.vue`
- **[x] 实时 `emit`**: 检查 `<script setup>` 中是否存在一个 `watch`,它正在监听本地的编辑状态,并在内容变化时**立即**通过 `emit('update:content', ...)` 通知父组件。
- **[x] 无 `prose` 类**: 检查组件模板中的 `class` 属性,确认其中没有 `@apply prose` 或其变体,以避免与自定义主题的样式冲突。
---
## Part 4: 架构一致性与错误处理
### 📍 **职责分离检查** ✅
- **[✅] 单一职责原则**: 每个 Composable 只负责一个明确的功能域,不应承担其他职责
- **[✅] 重复逻辑检查**: 确认没有多个 Composable 实现相同的功能(如模板管理、存储操作)
- **[✅] 初始化逻辑集中**: 相关资源的初始化逻辑应集中在一个地方,避免竞争条件
### 📍 **存储键管理** ✅
- **[✅] 统一存储键定义**: 所有存储键应定义在 `packages/ui/src/constants/storage-keys.ts`
- **[✅] 避免魔法字符串**: 不应在代码中直接使用字符串作为存储键
- **[✅] 存储键一致性**: 确认 DataManager 中的存储键与 UI 包中的定义保持同步
### 📍 **服务依赖管理** ✅
- **[✅] 统一服务获取**: 优先使用 `inject('services')` 获取服务,避免 props 和 inject 混用
- **[✅] 服务空值检查**: 如果 services 未正确注入,应立即抛出错误而不是静默处理
- **[✅] 立即失败原则**: 发现服务依赖问题时立即报错,不要使用重试机制掩盖问题
### 📍 **错误处理原则** ✅
- **[✅] 避免静默处理**: 不应使用 try-catch 静默处理错误,应让错误向上传播
- **[✅] 移除掩盖机制**: 不应有备用逻辑或重试机制掩盖真正的问题
- **[✅] 明确错误信息**: 错误信息应明确指出问题所在,便于快速定位
- **[✅] watch中的错误处理**: 即使在watch回调中也不应掩盖错误应让错误向上传播
### 📍 **事件处理一致性** ✅
- **[✅] v-model 优先**: 优先使用 v-model 双向绑定,避免复杂的事件处理链
- **[✅] 事件参数一致**: 确认组件发出的事件参数与处理函数期望的参数匹配
- **[✅] 异步事件处理**: 如果事件处理函数是异步的,确认调用方正确处理 Promise
### 📍 **架构分层检查** ✅
- **[✅] 插件层独立性**: 插件层(如 i18n.ts不应依赖UI组件层的常量或组件
- **[✅] 避免循环依赖**: 确认不同层级之间没有循环引用
- **[✅] 降级处理合理性**: 区分合理的降级处理和掩盖问题的静默处理
### 📍 **Electron兼容性检查** ✅
- **[✅] 存储实例一致性**: 确保i18n等插件使用与App.vue相同的存储实例避免UI进程和主进程数据不一致
- **[✅] 服务依赖注入**: 插件层应接收服务实例而不是自己创建确保Electron环境下的数据同步
- **[✅] 延迟初始化**: Web和Extension应用中的i18n都应等待存储服务准备好后再初始化
- **[✅] 避免main创建服务**: main.ts不应直接使用StorageFactory.createDefault()应由App.vue统一管理
- **[✅] 文件扩展名一致性**: Web和Extension应用都应使用main.ts而不是混用.js和.ts