diff --git a/apps/chat.js b/apps/chat.js index e8f5015..b411ccf 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -1931,112 +1931,132 @@ export class chatgpt extends plugin { if (conversation) { option = Object.assign(option, conversation) } - let isAdmin = e.sender.role === 'admin' || e.sender.role === 'owner' - let sender = e.sender.user_id - let serpTool - switch (Config.serpSource) { - case 'ikechan8370': { - serpTool = new SerpIkechan8370Tool() - break - } - case 'azure': { - if (!Config.azSerpKey) { - logger.warn('未配置bing搜索密钥,转为使用ikechan8370搜索源') + if (Config.smartMode) { + let isAdmin = e.sender.role === 'admin' || e.sender.role === 'owner' + let sender = e.sender.user_id + let serpTool + switch (Config.serpSource) { + case 'ikechan8370': { + serpTool = new SerpIkechan8370Tool() + break + } + case 'azure': { + if (!Config.azSerpKey) { + logger.warn('未配置bing搜索密钥,转为使用ikechan8370搜索源') + serpTool = new SerpIkechan8370Tool() + } else { + serpTool = new SerpTool() + } + break + } + default: { serpTool = new SerpIkechan8370Tool() - } else { - serpTool = new SerpTool() } - break } - default: { - serpTool = new SerpIkechan8370Tool() - } - } - let tools = [ - - // new SendAvatarTool(), - // new SendDiceTool(), - new EditCardTool(), - new QueryStarRailTool(), - new WebsiteTool(), - new JinyanTool(), - new KickOutTool(), - new WeatherTool(), - new SendPictureTool(), - serpTool - ] - let img = [] - if (e.source) { - // 优先从回复找图 - let reply - if (e.isGroup) { - reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message - } else { - reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message - } - if (reply) { - for (let val of reply) { - if (val.type === 'image') { - console.log(val) - img.push(val.url) + let tools = [ + // new SendAvatarTool(), + // new SendDiceTool(), + new EditCardTool(), + new QueryStarRailTool(), + new WebsiteTool(), + new JinyanTool(), + new KickOutTool(), + new WeatherTool(), + new SendPictureTool(), + serpTool + ] + let img = [] + if (e.source) { + // 优先从回复找图 + let reply + if (e.isGroup) { + reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message + } else { + reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message + } + if (reply) { + for (let val of reply) { + if (val.type === 'image') { + console.log(val) + img.push(val.url) + } } } } - } - if (e.img) { - img.push(...e.img) - } - if (img.length > 0 && Config.extraUrl) { - tools.push(new ImageCaptionTool()) - prompt += `\nthe url of the picture(s) above: ${img.join(', ')}` - } else { - tools.push(new SerpImageTool()) - tools.push(...[new SearchVideoTool(), - new SendVideoTool(), - new SearchMusicTool(), - new SendMusicTool()]) - } - // if (e.sender.role === 'admin' || e.sender.role === 'owner') { - // tools.push(...[new JinyanTool(), new KickOutTool()]) - // } - let funcMap = {} - tools.forEach(tool => { - funcMap[tool.name] = { - exec: tool.func, - function: tool.function() + if (e.img) { + img.push(...e.img) } - }) - if (!option.completionParams) { - option.completionParams = {} - } - option.completionParams.functions = Object.keys(funcMap).map(k => funcMap[k].function) - let msg - try { - msg = await this.chatGPTApi.sendMessage(prompt, option) - logger.info(msg) - while (msg.functionCall) { - let { name, arguments: args } = msg.functionCall - let functionResult = await funcMap[name].exec(Object.assign({ isAdmin, sender }, JSON.parse(args))) - logger.mark(`function ${name} execution result: ${functionResult}`) - option.parentMessageId = msg.id - option.name = name - msg = await this.chatGPTApi.sendMessage(functionResult, option, 'function') - logger.info(msg) - } - } catch (err) { - if (err.message?.indexOf('context_length_exceeded') > 0) { - logger.warn(err) - await redis.del(`CHATGPT:CONVERSATIONS:${e.sender.user_id}`) - await redis.del(`CHATGPT:WRONG_EMOTION:${e.sender.user_id}`) - await e.reply('字数超限啦,将为您自动结束本次对话。') - return null + if (img.length > 0 && Config.extraUrl) { + tools.push(new ImageCaptionTool()) + prompt += `\nthe url of the picture(s) above: ${img.join(', ')}` } else { - logger.error(err) - throw new Error(err) + tools.push(new SerpImageTool()) + tools.push(...[new SearchVideoTool(), + new SendVideoTool(), + new SearchMusicTool(), + new SendMusicTool()]) } + // if (e.sender.role === 'admin' || e.sender.role === 'owner') { + // tools.push(...[new JinyanTool(), new KickOutTool()]) + // } + let funcMap = {} + tools.forEach(tool => { + funcMap[tool.name] = { + exec: tool.func, + function: tool.function() + } + }) + if (!option.completionParams) { + option.completionParams = {} + } + option.completionParams.functions = Object.keys(funcMap).map(k => funcMap[k].function) + let msg + try { + msg = await this.chatGPTApi.sendMessage(prompt, option) + logger.info(msg) + while (msg.functionCall) { + let { name, arguments: args } = msg.functionCall + let functionResult = await funcMap[name].exec(Object.assign({ isAdmin, sender }, JSON.parse(args))) + logger.mark(`function ${name} execution result: ${functionResult}`) + option.parentMessageId = msg.id + option.name = name + // 不然普通用户可能会被openai限速 + await delay(300) + msg = await this.chatGPTApi.sendMessage(functionResult, option, 'function') + logger.info(msg) + } + } catch (err) { + if (err.message?.indexOf('context_length_exceeded') > 0) { + logger.warn(err) + await redis.del(`CHATGPT:CONVERSATIONS:${e.sender.user_id}`) + await redis.del(`CHATGPT:WRONG_EMOTION:${e.sender.user_id}`) + await e.reply('字数超限啦,将为您自动结束本次对话。') + return null + } else { + logger.error(err) + throw new Error(err) + } + } + return msg + } else { + let msg + try { + msg = await this.chatGPTApi.sendMessage(prompt, option) + } catch (err) { + if (err.message?.indexOf('context_length_exceeded') > 0) { + logger.warn(err) + await redis.del(`CHATGPT:CONVERSATIONS:${e.sender.user_id}`) + await redis.del(`CHATGPT:WRONG_EMOTION:${e.sender.user_id}`) + await e.reply('字数超限啦,将为您自动结束本次对话。') + return null + } else { + logger.error(err) + throw new Error(err) + } + } + return msg } - return msg } } } diff --git a/apps/help.js b/apps/help.js index 547e252..e488fe1 100644 --- a/apps/help.js +++ b/apps/help.js @@ -210,6 +210,11 @@ let helpData = [ icon: 'token', title: '#chatgpt设置后台刷新token', desc: '用于查看API余额。注意和配置的key保持同一账号。' + }, + { + icon: 'token', + title: '#chatgpt(开启|关闭)智能模式', + desc: 'API模式下打开或关闭智能模式。' } ] }, diff --git a/apps/management.js b/apps/management.js index d581d3f..0ac3688 100644 --- a/apps/management.js +++ b/apps/management.js @@ -1,8 +1,6 @@ import plugin from '../../../lib/plugins/plugin.js' import { Config } from '../utils/config.js' -import { exec } from 'child_process' import { - checkPnpm, formatDuration, getAzureRoleList, getPublicIP, @@ -260,6 +258,11 @@ export class ChatgptManagement extends plugin { reg: '^#chatgpt导入配置', fnc: 'importConfig', permission: 'master' + }, + { + reg: '^#chatgpt(开启|关闭)智能模式$', + fnc: 'switchSmartMode', + permission: 'master' } ] }) @@ -1006,6 +1009,7 @@ azure语音:Azure 语音是微软 Azure 平台提供的一项语音服务, } return true } + async versionChatGPTPlugin (e) { await renderUrl(e, `http://127.0.0.1:${Config.serverPort || 3321}/version`, { Viewport: { width: 800, height: 600 } }) } @@ -1391,7 +1395,7 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie }) console.log(configJson) const buf = Buffer.from(configJson) - e.friend.sendFile(buf, `ChatGPT-Plugin Config ${new Date}.json`) + e.friend.sendFile(buf, `ChatGPT-Plugin Config ${new Date()}.json`) return true } @@ -1419,8 +1423,8 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie if (Config[keyPath] != value) { changeConfig.push({ item: keyPath, - value: typeof(value) === 'object' ? JSON.stringify(value): value, - old: typeof(Config[keyPath]) === 'object' ? JSON.stringify(Config[keyPath]): Config[keyPath], + value: typeof (value) === 'object' ? JSON.stringify(value) : value, + old: typeof (Config[keyPath]) === 'object' ? JSON.stringify(Config[keyPath]) : Config[keyPath], type: 'config' }) Config[keyPath] = value @@ -1461,11 +1465,28 @@ Poe 模式会调用 Poe 中的 Claude-instant 进行对话。需要提供 Cookie } } } else { - await this.reply(`未找到配置文件`, false) + await this.reply('未找到配置文件', false) return false } this.finish('doImportConfig') } + async switchSmartMode (e) { + if (e.msg.includes('开启')) { + if (Config.smartMode) { + await e.reply('已经开启了') + return + } + Config.smartMode = true + await e.reply('好的,已经打开智能模式,注意API额度哦') + } else { + if (!Config.smartMode) { + await e.reply('已经是关闭得了') + return + } + Config.smartMode = false + await e.reply('好的,已经关闭智能模式') + } + } } diff --git a/guoba.support.js b/guoba.support.js index 9a76c7e..2868293 100644 --- a/guoba.support.js +++ b/guoba.support.js @@ -317,9 +317,15 @@ export function supportGuoba () { { field: 'model', label: 'OpenAI 模型', - bottomHelpMessage: 'gpt-4, gpt-4-0314, gpt-4-32k, gpt-4-32k-0314, gpt-3.5-turbo, gpt-3.5-turbo-0301。默认为gpt-3.5-turbo,gpt-4需账户支持', + bottomHelpMessage: 'gpt-4, gpt-4-0613, gpt-4-32k, gpt-4-32k-0613, gpt-3.5-turbo, gpt-3.5-turbo-0613, gpt-3.5-turbo-16k-0613。默认为gpt-3.5-turbo,gpt-4需账户支持', component: 'Input' }, + { + field: 'smartMode', + label: '智能模式', + bottomHelpMessage: '仅建议gpt-4-32k和gpt-3.5-turbo-16k-0613开启,gpt-4-0613也可。开启后机器人可以群管、收发图片、发视频发音乐、联网搜索等。注意较费token。', + component: 'Switch' + }, { field: 'openAiBaseUrl', label: 'OpenAI API服务器地址', diff --git a/utils/config.js b/utils/config.js index d50e42e..f20c1bf 100644 --- a/utils/config.js +++ b/utils/config.js @@ -129,6 +129,7 @@ const defaultConfig = { azSerpKey: '', serpSource: 'ikechan8370', extraUrl: 'https://cpe.ikechan8370.com', + smartMode: false, version: 'v2.7.0' } const _path = process.cwd()