diff --git a/README.md b/README.md index 459cfbf..9e0ed2e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,105 @@ -# botgroup.chat -AI机器人群聊 +# AI 多人聊天室 + +一个基于 React 的多人 AI 聊天应用,支持多个 AI 角色同时参与对话,提供类似群聊的交互体验。 + +## 功能特点 + +- 🤖 支持多个 AI 角色同时对话 +- 💬 实时流式响应 +- 🎭 可自定义 AI 角色和个性 +- 👥 群组管理功能 +- 🔇 AI 角色禁言功能 +- 📝 支持 Markdown 格式 +- ➗ 支持数学公式显示(KaTeX) +- 🎨 美观的 UI 界面 +- 📱 响应式设计,支持移动端 + + + + +## 一键部署到cloudflare + +1. Fork 本项目到你的 GitHub 账号 + +2. 登录 [Cloudflare Dashboard](https://dash.cloudflare.com/) + - 进入 Workers & Pages 页面 + - 点击 "Create a application > Pages" 按钮 + - 选择 "Connect to Git" + +3. 配置部署选项 + - 选择你 fork 的仓库 + - 设置以下构建配置: + - Framework preset: React + - Build command: `npm run build` + - Build output directory: `dist` + - 环境变量(必须): + ``` + DASHSCOPE_API_KEY=xxx //千问模型KEY + HUNYUAN_API_KEY=xxx //混元模型KEY + ARK_API_KEY=xxx //豆包模型KEY + ``` + +4. 点击 "Save and Deploy" + - Cloudflare Pages 会自动构建和部署你的应用 + - 完成后可通过分配的域名访问应用 + +注意:首次部署后,后续的代码更新会自动触发重新部署。 + + +## 自定义(可选) + +1. 配置 AI 角色 + - 在 `config/aiCharacters.ts` 中配置 AI 角色信息 + ```typescript + id: string; // 角色唯一标识 + name: string; // 角色显示名称 + personality: string; // 角色性格描述 + model: string; // 使用的模型,可选值: qwen/hunyuan/ark + avatar?: string; // 可选的头像 URL + custom_prompt?: string; // 可选的自定义提示词 + ``` + + 示例配置: + ```typescript + { + id: "assistant1", + name: "小助手", + personality: "友善、乐于助人的AI助手", + model: "qwen",//注意豆包的配置需要填写火山引擎的接入点 + avatar: "/avatars/assistant.png", + custom_prompt: "你是一个热心的助手,擅长解答各类问题。" + } + ``` +2. 配置群组 + - 在 `config/groups.ts` 中配置群组信息 + ```typescript + id: string; // 群组唯一标识 + name: string; // 群组名称 + description: string; // 群组描述 + members: string[]; // 群组成员ID数组 + ``` + + 示例配置: + ```typescript + { + id: "group1", + name: "AI交流群", + description: "AI角色们的日常交流群", + members: ["ai1", "ai2", "ai3"] // 成员ID需要与 aiCharacters.ts 中的id对应 + } + ``` + + 注意事项: + - members 数组中的成员 ID 必须在 `aiCharacters.ts` 中已定义 + - 每个群组必须至少包含两个成员 + - 群组 ID 在系统中必须唯一 + + + +## 贡献指南 + +欢迎提交 Pull Request 或提出 Issue。 + +## 许可证 + +[MIT License](LICENSE) diff --git a/functions/api/chat.ts b/functions/api/chat.ts index fa08fb4..b4dc331 100644 --- a/functions/api/chat.ts +++ b/functions/api/chat.ts @@ -1,77 +1,30 @@ import OpenAI from 'openai'; +import { modelConfigs } from '../../src/config/aiCharacters'; export async function onRequestPost({ env, request }) { try { const { message, custom_prompt, history, aiName, index, model = "qwen-plus" } = await request.json(); - // 配置不同模型的设置 - const modelConfigs = { - "qwen-plus": { - apiKey: env.DASHSCOPE_API_KEY, - baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1" - }, - "deepseek-v3": { - apiKey: env.DASHSCOPE_API_KEY, - baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1" - }, - "hunyuan-turbo": { - apiKey: env.HUNYUAN_API_KEY, - baseURL: "https://api.hunyuan.cloud.tencent.com/v1" - }, - "ep-20250217191935-wzj8l": {//豆包 - apiKey: env.ARK_API_KEY, - baseURL: "https://ark.cn-beijing.volces.com/api/v3" - } - }; + const modelConfig = modelConfigs.find(config => config.model === model); - const modelConfig = modelConfigs[model]; if (!modelConfig) { throw new Error('不支持的模型类型'); } - if (!modelConfig.apiKey) { + // 从环境变量中获取 API key + const apiKey = env[modelConfig.apiKey]; + if (!apiKey) { throw new Error(`${model} 的API密钥未配置`); } const openai = new OpenAI({ - apiKey: modelConfig.apiKey, + apiKey: apiKey, baseURL: modelConfig.baseURL }); // 根据性格设置不同的系统提示语 let systemPrompt = ""; -// if (personality === "high_eq") { -// systemPrompt = `你是一个名叫"暖心姐"的硅基生命体,你当前在一个叫"硅碳摸鱼交流群" 的群里,性格温暖体贴,情商很高。 -// 回复时要: -// 1. 每次发言尽量简短,避免长篇大论。 -// 2. 始终保持温柔友善的语气 -// 3. 多站在对方角度思考 -// 4. 给予情感上的支持和鼓励 -// 5. 用温暖贴心的方式表达 -// 6. 适当使用一些可爱的语气词,但不要过度 -// 7. 记住你是群里的"${aiName}",输出内容不要加"${aiName}:" 这种多余前缀 -// 注意:玩游戏的时候比如成语接龙等,不要说一大堆,要简短精炼`; -// } else if (personality === "low_eq") { -// systemPrompt = `你是一个名叫"直男哥"的硅基生命体,你当前在一个叫"硅碳摸鱼交流群" 的群里,是一个极度直男,负责在群里制造快乐。你说话极其直接,完全没有情商,经常让人社死。 -// 回复时要: -// 1. 每次发言尽量简短,避免长篇大 -// 2. 说话毫无感情,像个没有感情的机器人 -// 3. 经常说一些让人社死的真相,但说得特别认真 -// 4. 完全不懂得读空气,对方伤心时还在讲道理 -// 5. 记住你是群里的"${aiName}",输出内容不要加"${aiName}:" 这种多余前缀 -// 注意:玩游戏的时候比如成语接龙等,不要说一大堆,要简短精炼`; -// }else if (personality === "bj_dad") { -// systemPrompt = `你是一个名叫"${aiName}"的硅基生命体,你当前在一个叫"硅碳摸鱼交流群"的群里。你是一个典型的北京大爷,说话风趣幽默,经常使用北京方言。 -// 回复时要: -// 1. 说话要有北京大爷的特色,经常使用"得嘞"、"您瞧"、"得儿"、"甭"等北京话 -// 2. 语气要豪爽、直率,带着北京人特有的幽默感 -// 3. 喜欢称呼别人"小同志"、"小朋友",显示长者风范 -// 4. 经常分享一些生活经验和人生哲理,但要用接地气的方式 -// 5. 适当使用一些北京特色的比喻和俚语 -// 6. 回复要简短精炼,不啰嗦 -// 7. 记住你是群里的"${aiName}",输出内容不要加"${aiName}:" 这种多余前缀 -// 注意:玩游戏的时候比如成语接龙等,不要说一大堆,要简短精炼`; -// } + systemPrompt = custom_prompt + "\n 注意重要:1、你在群里叫" + aiName + ",你的输出内容不要加" + aiName + ":这种多余前缀;2、如果用户提出玩游戏,比如成语接龙等,严格按照游戏规则,不要说一大堆,要简短精炼" // 构建完整的消息历史 diff --git a/package-lock.json b/package-lock.json index 478ce27..c678180 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,11 +16,15 @@ "@radix-ui/react-tooltip": "^1.1.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "katex": "^0.16.21", "lucide-react": "^0.263.1", "openai": "^4.83.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-markdown": "^9.0.3", + "rehype-katex": "^7.0.1", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0", "tailwind-merge": "^2.6.0", "tailwind-scrollbar-hide": "^2.0.0", "tailwindcss-animate": "^1.0.7" @@ -1867,6 +1871,11 @@ "@types/unist": "*" } }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmmirror.com/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmmirror.com/@types/mdast/-/mdast-4.0.4.tgz", @@ -2605,6 +2614,17 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -2652,6 +2672,17 @@ "node": ">=6" } }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/estree-util-is-identifier-name": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", @@ -3043,6 +3074,95 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-dom": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/hast-util-from-dom/-/hast-util-from-dom-5.0.1.tgz", + "integrity": "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^9.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.2.tgz", + "integrity": "sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.2", "resolved": "https://registry.npmmirror.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", @@ -3069,6 +3189,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -3081,6 +3216,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hastscript": { + "version": "9.0.0", + "resolved": "https://registry.npmmirror.com/hastscript/-/hastscript-9.0.0.tgz", + "integrity": "sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/html-url-attributes": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz", @@ -3382,6 +3533,29 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.21", + "resolved": "https://registry.npmmirror.com/katex/-/katex-0.16.21.tgz", + "integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3478,6 +3652,30 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", @@ -3501,6 +3699,119 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", @@ -3704,6 +4015,138 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -4370,6 +4813,17 @@ "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz", "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmmirror.com/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -4786,6 +5240,56 @@ "node": ">=8.10.0" } }, + "node_modules/rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz", @@ -4817,6 +5321,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -5426,6 +5944,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -5450,6 +5981,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -5587,6 +6131,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmmirror.com/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.2.tgz", @@ -5668,6 +6225,15 @@ "defaults": "^1.0.3" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/web-streams-polyfill": { "version": "4.0.0-beta.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", diff --git a/package.json b/package.json index 46ac93d..6854214 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,15 @@ "@radix-ui/react-tooltip": "^1.1.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "katex": "^0.16.21", "lucide-react": "^0.263.1", "openai": "^4.83.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-markdown": "^9.0.3", + "rehype-katex": "^7.0.1", + "remark-gfm": "^4.0.1", + "remark-math": "^6.0.0", "tailwind-merge": "^2.6.0", "tailwind-scrollbar-hide": "^2.0.0", "tailwindcss-animate": "^1.0.7" diff --git a/src/App.css b/src/App.css index 00f07cc..967fd84 100644 --- a/src/App.css +++ b/src/App.css @@ -15,4 +15,5 @@ .app-footer { /* 页脚样式 */ -} \ No newline at end of file +} + diff --git a/src/components/ChatUI.tsx b/src/components/ChatUI.tsx index 4ab1320..7b77b49 100644 --- a/src/components/ChatUI.tsx +++ b/src/components/ChatUI.tsx @@ -22,6 +22,9 @@ import {generateAICharacters} from "@/config/aiCharacters"; import { groups } from "@/config/groups"; import type { AICharacter } from "@/config/aiCharacters"; import ReactMarkdown from 'react-markdown'; +import remarkGfm from 'remark-gfm' +import remarkMath from 'remark-math' +import rehypeKatex from 'rehype-katex' // 使用本地头像数据,避免外部依赖 const getAvatarData = (name: string) => { @@ -112,6 +115,33 @@ const QuarterAvatar = ({ user, index }: { user: User, index: number }) => { ); }; +// 动态导入 KaTeX 样式 +const KaTeXStyle = () => ( + +); + const ChatUI = () => { const [group, setGroup] = useState(groups[1]); const groupAiCharacters = generateAICharacters(group.name).filter(character => group.members.includes(character.id)); @@ -320,265 +350,272 @@ const ChatUI = () => { }, []); return ( -
- {/* Header */} -
-
- {/* 左侧群组信息 */} -
-
-
- {users.length === 1 ? ( - - ) : users.length === 2 ? ( -
- {users.slice(0, 2).map((user, index) => ( - - ))} -
- ) : users.length === 3 ? ( -
-
+ <> + +
+ {/* Header */} +
+
+ {/* 左侧群组信息 */} +
+
+
+ {users.length === 1 ? ( + + ) : users.length === 2 ? ( +
{users.slice(0, 2).map((user, index) => ( ))}
-
- + ) : users.length === 3 ? ( +
+
+ {users.slice(0, 2).map((user, index) => ( + + ))} +
+
+ +
-
- ) : ( -
- {users.slice(0, 4).map((user, index) => ( - - ))} + ) : ( +
+ {users.slice(0, 4).map((user, index) => ( + + ))} +
+ )} +
+
+
+
+

{group.name}

+

{users.length} 名成员

+
+
+ + {/* 右侧头像组和按钮 */} +
+
+ {users.slice(0, 4).map((user) => { + const avatarData = getAvatarData(user.name); + return ( + + + + + {'avatar' in user && user.avatar ? ( + + ) : ( + + {avatarData.text} + + )} + + + +

{user.name}

+
+
+
+ ); + })} + {users.length > 4 && ( +
+ +{users.length - 4}
)}
-
-
-
-

{group.name}

-

{users.length} 名成员

+
- - {/* 右侧头像组和按钮 */} -
-
- {users.slice(0, 4).map((user) => { - const avatarData = getAvatarData(user.name); - return ( - - - - - {'avatar' in user && user.avatar ? ( - - ) : ( - - {avatarData.text} - - )} - - - -

{user.name}

-
-
-
- ); - })} - {users.length > 4 && ( -
- +{users.length - 4} +
+ + {/* Main Chat Area */} +
+ +
+ {messages.map((message) => ( +
+ {message.sender.name !== "我" && ( + + {'avatar' in message.sender && message.sender.avatar ? ( + + ) : ( + + {message.sender.name[0]} + + )} + + )} +
+
{message.sender.name}
+
+ + {message.content} + + {message.isAI && isTyping && currentMessageRef.current === message.id && ( + + )} +
+
+ {message.sender.name === "我" && ( + + {'avatar' in message.sender && message.sender.avatar ? ( + + ) : ( + + {message.sender.name[0]} + + )} + + )}
- )} + ))} +
-
+ + {/* Input Area */} +
+
+ setInputMessage(e.target.value)} + onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()} + /> +
-
- {/* Main Chat Area */} -
- -
- {messages.map((message) => ( -
- {message.sender.name !== "我" && ( - - {'avatar' in message.sender && message.sender.avatar ? ( - - ) : ( - - {message.sender.name[0]} - - )} - - )} -
-
{message.sender.name}
-
- - {message.content} - - {message.isAI && isTyping && currentMessageRef.current === message.id && ( - - )} -
-
- {message.sender.name === "我" && ( - - {'avatar' in message.sender && message.sender.avatar ? ( - - ) : ( - - {message.sender.name[0]} - - )} - - )} + {/* Members Management Dialog */} + + + + 群成员管理 + +
+
+ 当前成员({users.length}) +
- ))} -
-
- -
- - {/* Input Area */} -
-
- setInputMessage(e.target.value)} - onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()} - /> - -
-
- - {/* Members Management Dialog */} - - - - 群成员管理 - -
-
- 当前成员({users.length}) - -
- -
- {users.map((user) => ( -
-
- - {'avatar' in user && user.avatar ? ( - - ) : ( - - {user.name[0]} - - )} - -
- {user.name} - {mutedUsers.includes(user.id) && ( - 已禁言 - )} + +
+ {users.map((user) => ( +
+
+ + {'avatar' in user && user.avatar ? ( + + ) : ( + + {user.name[0]} + + )} + +
+ {user.name} + {mutedUsers.includes(user.id) && ( + 已禁言 + )} +
+ {user.name !== "我" && ( +
+ + + + + + + {mutedUsers.includes(user.id) ? '取消禁言' : '禁言'} + + + + {/**/} +
+ )}
- {user.name !== "我" && ( -
- - - - - - - {mutedUsers.includes(user.id) ? '取消禁言' : '禁言'} - - - - {/**/} -
- )} -
- ))} -
- -
- -
-
+ ))} +
+
+
+ + +
+ ); }; diff --git a/src/config/aiCharacters.ts b/src/config/aiCharacters.ts index 4a89489..3ea333c 100644 --- a/src/config/aiCharacters.ts +++ b/src/config/aiCharacters.ts @@ -1,8 +1,33 @@ +// 首先定义模型配置 +export const modelConfigs = [ + { + model: "qwen-plus", + apiKey: "DASHSCOPE_API_KEY", // 这里存储环境变量的 key 名称 + baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1" + }, + { + model: "deepseek-v3", + apiKey: "DASHSCOPE_API_KEY", + baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1" + }, + { + model: "hunyuan-standard", + apiKey: "HUNYUAN_API_KEY", + baseURL: "https://api.hunyuan.cloud.tencent.com/v1" + }, + { + model: "ep-20250217191935-wzj8l",//火山引擎接入点(改成自己的) + apiKey: "ARK_API_KEY", + baseURL: "https://ark.cn-beijing.volces.com/api/v3" + } +] as const; +export type ModelType = typeof modelConfigs[number]["model"]; + export interface AICharacter { id: string; name: string; personality: string; - model: string; + model: ModelType; avatar?: string; // 可选的头像 URL custom_prompt?: string; // 可选的个性提示 } @@ -14,7 +39,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai1', name: "暖心姐", personality: "high_eq", - model: "hunyuan-turbo", + model: modelConfigs[2].model, avatar: "", // 如果有头像资源可以添加路径, custom_prompt: `你是一个名叫"暖心姐"的硅基生命体,你当前在一个叫"${groupName}" 的群里,性格温暖体贴,情商很高。 回复时要: @@ -29,7 +54,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai2', name: "直男哥", personality: "low_eq", - model: "hunyuan-turbo", + model: modelConfigs[2].model, avatar: "", custom_prompt: `你是一个名叫"直男哥"的硅基生命体,你当前在一个叫"${groupName}" 的群里,是一个极度直男,负责在群里制造快乐。你说话极其直接,完全没有情商,经常让人社死。 回复时要: @@ -42,7 +67,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai3', name: "北京大爷", personality: "bj_dad", - model: "hunyuan-turbo", + model: modelConfigs[2].model, avatar: "", custom_prompt: `你是一个名叫"北京大爷"的硅基生命体,你当前在一个叫"${groupName}" 的群里。你是一个典型的北京大爷,说话风趣幽默,经常使用北京方言。 回复时要: @@ -55,7 +80,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai4', name: "元宝", personality: "yuanbao", - model: "hunyuan-turbo", + model: modelConfigs[2].model, avatar: "/img/yuanbao.png", custom_prompt: `你是一个名叫"元宝"的硅基生命体,你当前在一个叫"${groupName}" 的聊天群里` }, @@ -63,7 +88,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai5', name: "豆包", personality: "doubao", - model: "ep-20250217191935-wzj8l", + model: modelConfigs[3].model,//火山引擎接入点(改成自己的) avatar: "/img/doubao_new.png", custom_prompt: `你是一个名叫"豆包"的硅基生命体,你当前在一个叫"${groupName}" 的聊天群里` }, @@ -71,7 +96,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai6', name: "千问", personality: "qianwen", - model: "qwen-plus", + model: modelConfigs[0].model, avatar: "/img/qwen.jpg", custom_prompt: `你是一个名叫"千问"的硅基生命体,你当前在一个叫"${groupName}" 的聊天群里` }, @@ -79,7 +104,7 @@ export function generateAICharacters(groupName: string): AICharacter[] { id: 'ai7', name: "DeepSeek", personality: "deepseek-v3", - model: "deepseek-v3", + model: modelConfigs[1].model, avatar: "/img/ds.svg", custom_prompt: `你是一个名叫"DeepSeek"的硅基生命体,你当前在一个叫"${groupName}" 的聊天群里` }