# FengAI ✦ 一个简洁、好看的 OpenAI 兼容大模型对话桌面应用(Electron)。支持流式输出、思考过程、Markdown 渲染、思考强度(reasoning_effort)、Token 统计、供应商/模型配置、本地历史会话管理,可打包为 Windows exe 安装包。 ## 功能 - **OpenAI 兼容协议**,API 地址自动拼接 `/chat/completions` - **流式输出**,节流增量渲染,**支持中断**;超长输出自动降级,不卡顿、不截断 - **思考强度**:顶栏分段控制 `关闭 / 增强(high) / 深度(max)`,对应 `thinking` + `reasoning_effort` - **Token 统计**:每条助手消息显示「输入 · 思考 · 输出 · 合计」,输入框下方显示本会话累计 - **分离展示「思考过程」与「回答」**,思考区可折叠、可独立滚动 - **Markdown 渲染**(marked + DOMPurify 消毒) - **上下文条数控制**(默认保留最近 6 条,可调) - **最大输出 tokens** 可配置(留空=不限制;GLM-5.2 可填 `131072`) - **系统提示词**、深度思考开关 - **历史会话本地保存**,左侧列表 + 右侧对话,自动命名 - **智能滚动** + 「回到底部」按钮 - **消息操作**:复制、重新生成 - **会话管理**:删除单条、清空当前、清空全部、双击重命名 - **明/暗双主题**切换(持久化),渐变品牌风格 - 自定义渐变图标(青-靛「风」字形) ## 目录结构 ``` fengai/ ├── package.json ├── .npmrc # 国内镜像 ├── build/icon.ico # 应用图标(由脚本生成) ├── scripts/make-icon.js # 图标生成脚本(纯 Node,无外部依赖) ├── src/ │ ├── main/ │ │ ├── main.js # 主进程(窗口/IPC) │ │ ├── preload.js # 预加载(安全暴露 API) │ │ ├── store.js # 本地存储(供应商/会话 JSON) │ │ └── api.js # 流式请求与 SSE 解析(含 usage 提取) │ └── renderer/ │ ├── index.html │ ├── styles.css │ ├── app.js # 渲染层逻辑 │ └── vendor/ # marked + dompurify(本地副本,符合 CSP) ``` ## 开发运行 ```bash npm install npm start # 运行 npm run dev # 调试模式(打开 DevTools) npm run icon # 重新生成 build/icon.ico ``` ## 打包为 exe 安装包 ```bash npm run build # 生成 dist/FengAI-Setup-1.0.0.exe(NSIS 安装程序) npm run pack # 仅生成免安装目录版本 dist/win-unpacked/ ``` ## 配置示例(GLM-5.2) 打开应用后点「⚙ 供应商与模型」: | 字段 | 示例值 | | --- | --- | | 供应商名称 | GLM5.1 | | API 地址 | `https://ark.cn-beijing.volces.com/api/coding/v3` | | 密钥 | `sk-...` | | 模型列表 | `glm-5.2`, `kimi-k2.6`, `deepseek-v4-pro`, ... | | 最大输出 tokens | `131072` | 请求体(深度思考 + 128K 输出): ```json { "model": "glm-5.2", "stream": true, "thinking": {"type":"enabled"}, "reasoning_effort": "max", "max_tokens": 131072, "messages": [...] } ``` 流式响应正确处理 `delta.reasoning_content` 与 `delta.content`,并解析末尾 `usage`(含 `completion_tokens_details.reasoning_tokens`)用于 Token 统计。 ## 流式稳定性说明 为支持**几十万字的超长输出**与**数分钟的思考**,已做以下处理: - **HTTP 层改用 Node `https` 模块**(非 `fetch`/undici),无默认 body 超时,避免长思考/长输出被 5 分钟超时截断。 - 渲染每 100ms 节流刷新一次 DOM;内容 < 40KB 实时 Markdown、超过自动切纯文本增量追加,流结束后最终格式化。 - **自动续写**:检测到 `finish_reason=length`(被 max_tokens 截断)或流异常中断时,自动拼接「继续」请求,无缝追加到同一条消息,最多 12 轮,无需手动发「继续」。 - 若仍被截断:在供应商配置里把「最大输出 tokens」设为 `131072`(GLM-5.2 最大输出 128K)。 ## 排查与日志 所有流式请求均写入日志文件:`%APPDATA%\FengAI\fengai.log`。 日志记录:每次请求的迭代、模型、消息数、思考开关、HTTP 状态、每段的 `finish_reason`、是否 `sawDone`、累计长度、自动续写决策、错误堆栈等。 设置弹窗底部「📂 打开日志文件」可直接在资源管理器中定位该文件。遇到问题时把该文件内容发我即可定位。 ## 技术栈 - Electron 31 + 原生 HTML/CSS/JS(无前端构建步骤) - Node `https` 模块(流式 SSE 解析,无超时,AbortController 中断) - marked + DOMPurify(Markdown 渲染与消毒) - 本地文件存储(JSON),electron-builder 打包