diff --git a/package.json b/package.json index d185aab..83161aa 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,10 @@ "random": "^4.1.0", "undici": "^5.21.0", "uuid": "^9.0.0", - "ws": "^8.13.0" + "ws": "^8.13.0", + "js-tiktoken": "^1.0.5", + "quick-lru": "6.1.1" + }, "optionalDependencies": { "@node-rs/jieba": "^1.6.2", diff --git a/utils/tools/EliMovieTool.js b/utils/tools/EliMovieTool.js index 6c9c227..1b4efdb 100644 --- a/utils/tools/EliMovieTool.js +++ b/utils/tools/EliMovieTool.js @@ -27,15 +27,14 @@ export class EliMovieTool extends AbstractTool { let avocado try { // eslint-disable-next-line camelcase - let { AvocadoRuleALL } = await import('../../../avocado-plugin/apps/avocado.js') - avocado = new AvocadoRuleALL(e) + let { AvocadoMovie } = await import('../../../avocado-plugin/apps/avocadoMovie.js') + avocado = new AvocadoMovie(e) } catch (err1) { return 'the user didn\'t install avocado-plugin. suggest him to install' } try { // eslint-disable-next-line new-cap - e.senderFromChatGpt = e.sender.user_id - await avocado.avocadoMovie(e) + await avocado.getHotMovies(e) return 'notify the user that the movie has been sent to them and they can obtain more information by sending commands displayed in the picture. you don’t need to search for additional information to reply! just simply inform them that you have completed your task!!!' } catch (err) { logger.warn(err) diff --git a/utils/tools/EliMusicTool.js b/utils/tools/EliMusicTool.js index 68aea44..4d9497d 100644 --- a/utils/tools/EliMusicTool.js +++ b/utils/tools/EliMusicTool.js @@ -5,75 +5,82 @@ export class EliMusicTool extends AbstractTool { parameters = { properties: { - keyword: { + keywordOrSongName: { type: 'string', - description: 'Not necessarily a songName, it can be some descriptive words, but does not include the singer\'s name! can be left blank!' + description: 'Not necessarily a songName, it can be some descriptive words.' }, singer: { type: 'string', - description: 'Singer name, multiple singers are separated by \',\'! can be left blank!' + description: 'Singer name, multiple singers are separated by \',\'!' }, isRandom: { type: 'boolean', - description: 'Whether to randomly select songs, default is false' - }, - isRandom2: { - type: 'boolean', - description: 'when isRandom is true and neither singer nor songName is specified!!!, this value is true; otherwise, it is false. The default value is false.' + description: 'true when randomly select songs' }, isHot: { type: 'boolean', - description: 'Whether it\'s related to \'hot\', consider filling in this item when there is no song name, can be left blank' + description: 'true when user\'s needs related to \'hot\'' }, - singerRegion: { + singerTypeOrRegion: { type: 'string', - description: 'Whether it\'s related to \'hot\', consider filling in this item when there is no song name, can be left blank' + description: 'Choose from [华语|中国|欧美|韩国|日本] when seeking the latest ranking of popular vocalists.' }, isRelax: { type: 'boolean', - description: 'Fill in when the user wants to sleep or rest, leave others blank when filling in this item, default is false' + description: 'Complete whenever you wish to discover the renowned vocalist in a particular locale.' } }, - required: ['keyword', 'singer', 'isRandom', 'singerRegion, isRelax', 'isRandom2'] + required: ['keywordOrSongName', 'singer', 'isRandom', 'singerTypeOrRegion, isRelax'] } - description = 'It is very useful when you want to meet the music needs or of users or when users want to sleep or unwind., so you should use this tool as much as possible, regardless of whether I asked you before!' + description = 'It is very useful when you want to meet the music needs of user or when user want to sleep or unwind(give him a relax music).' func = async function (opts, e) { - let { keyword, singer, isRandom, isHot, singerRegion, isRelax, isRandom2 } = opts - let avocado + let { keywordOrSongName, singer, isRandom, isHot, singerTypeOrRegion, isRelax } = opts + let avocado, songDetail, musicUtils try { let { AvocadoMusic } = await import('../../../avocado-plugin/apps/avocadoMusic.js') + musicUtils = await import('../../../avocado-plugin/utils/music.js') avocado = new AvocadoMusic(e) } catch (err) { return 'the user didn\'t install avocado-plugin. suggest him to install' } try { - // 不听话的gpt - isRandom2 = !keyword && isRandom && !isRandom2 && !singer - if (isRandom2) { + // 条件成立则随机播放最爱歌手的音乐 + const orderFavSinger = !keywordOrSongName && isRandom && !singer + + if (orderFavSinger) { // 随机播放最爱歌手的音乐, 需要通过指令设置 try { singer = await redis.get(`AVOCADO:MUSIC_${e.sender.user_id}_FAVSINGER`) if (!singer) throw new Error('no favorite singer') - singer = JSON.parse(singer).singer - logger.warn(singer) + singer = JSON.parse(singer).singerName } catch (err) { return 'the user didn\'t set a favorite singer. Suggest setting it through the command \'#设置歌手+歌手名称\'!' } - e.msg = '#鳄梨酱#随机' + singer - } else if (isRelax) { - e.msg = '#鳄梨酱#随机放松' - } else if (singerRegion) { - e.msg = '#鳄梨酱#' + (isRandom ? '随机' : '') + (isHot ? '热门' : '') + singerRegion + '歌手' - } else { - e.msg = '#鳄梨酱#' + (isRandom ? '随机' : '') + (isHot ? '热门' : '') + (singer ? singer + (keyword ? ',' + keyword : '') : keyword) + e.msg = '#鳄梨酱音乐#随机' + singer + } else if (isRelax) { // 随机发送放松音乐 + const arr = ['安静', '放松', '宁静', '白噪音'] + e.msg = `#鳄梨酱音乐#随机${arr[Math.floor(Math.random() * arr.length)]}` + } else if (singerTypeOrRegion) { // 查看热门歌手榜单 + if (['华语', '中国', '欧美', '韩国', '日本'].includes(singerTypeOrRegion)) { + e.msg = '#鳄梨酱音乐#' + (isRandom ? '随机' : '') + (!keywordOrSongName && isHot ? '热门' : '') + singerTypeOrRegion + '歌手' + } + } else { // 正常点歌 + if (singer && keywordOrSongName) { + isRandom = false // 有时候ai会随意设置这个参数,降低权重 + songDetail = await musicUtils.getOrderSongList(e.sender.user_id, singer + ',' + keywordOrSongName, 1) + } + e.msg = '#鳄梨酱音乐#' + (isRandom ? '随机' : '') + (!keywordOrSongName && isHot ? '热门' : '') + (singer ? singer + (keywordOrSongName ? ',' + keywordOrSongName : '') : keywordOrSongName) } - e.senderFromChatGpt = e.sender.user_id await avocado.pickMusic(e) - if (isRandom2) { - return 'tell the user that a random song by his favorite artist has been sent to him! you don\'t need to find other info!' + if (orderFavSinger) { + return 'tell the user that a random song by his favorite artist has been sent to him!' } else { - return 'tell user that the response of his request has been sent to the user! you don\'t need to find other info!' + return 'tell user that the response of his request has been sent to the him!' + + (songDetail + ? 'song detail is: ' + JSON.stringify(songDetail) + ' and send album picture to user' + : '' + ) } } catch (e) { return `music share failed: ${e}` diff --git a/utils/tools/SendAudioMessageTool.js b/utils/tools/SendAudioMessageTool.js index 4600700..dcbab9f 100644 --- a/utils/tools/SendAudioMessageTool.js +++ b/utils/tools/SendAudioMessageTool.js @@ -67,9 +67,10 @@ export class SendAudioMessageTool extends AbstractTool { let { pendingText, ttsMode, vitsModeRole, azureModeRole, voxModeRole, speakingEmotion, speakingEmotionDegree, targetGroupIdOrQQNumber } = opts let sendable ttsMode = isNaN(ttsMode) || !ttsMode ? 1 : ttsMode + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(targetGroupIdOrQQNumber.trim()) + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) try { switch (ttsMode) { case 1: diff --git a/utils/tools/SendAvatarTool.js b/utils/tools/SendAvatarTool.js index 8efff0a..daf2b00 100644 --- a/utils/tools/SendAvatarTool.js +++ b/utils/tools/SendAvatarTool.js @@ -23,9 +23,10 @@ export class SendAvatarTool extends AbstractTool { if (!pictures.length) { return 'there is no valid qq' } + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(targetGroupIdOrQQNumber.trim()) + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) let groupList = await Bot.getGroupList() console.log('sendAvatar', target, pictures) diff --git a/utils/tools/SendBilibiliTool.js b/utils/tools/SendBilibiliTool.js index b6a120b..b7b15c8 100644 --- a/utils/tools/SendBilibiliTool.js +++ b/utils/tools/SendBilibiliTool.js @@ -23,9 +23,11 @@ export class SendVideoTool extends AbstractTool { func = async function (opts, e) { let { id, targetGroupIdOrQQNumber } = opts // 非法值则发送到当前群聊或私聊 + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(targetGroupIdOrQQNumber.trim()) + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) + let msg = [] try { let { arcurl, title, pic, description, videoUrl, headers, bvid, author, play, pubdate, like, honor } = await getBilibili(id) diff --git a/utils/tools/SendDiceTool.js b/utils/tools/SendDiceTool.js index f85ab75..0e5dc46 100644 --- a/utils/tools/SendDiceTool.js +++ b/utils/tools/SendDiceTool.js @@ -20,9 +20,10 @@ export class SendDiceTool extends AbstractTool { func = async function (opts, e) { let { num, targetGroupIdOrQQNumber } = opts // 非法值则发送到当前群聊或私聊 + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(targetGroupIdOrQQNumber.trim()) + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) let groupList = await Bot.getGroupList() num = isNaN(num) || !num ? 1 : num > 5 ? 5 : num if (groupList.get(target)) { diff --git a/utils/tools/SendMessageToSpecificGroupOrUserTool.js b/utils/tools/SendMessageToSpecificGroupOrUserTool.js index 31c9dcb..7a29f81 100644 --- a/utils/tools/SendMessageToSpecificGroupOrUserTool.js +++ b/utils/tools/SendMessageToSpecificGroupOrUserTool.js @@ -10,7 +10,7 @@ export class SendMessageToSpecificGroupOrUserTool extends AbstractTool { type: 'string', description: 'text to be sent' }, - target: { + targetGroupIdOrQQNumber: { type: 'string', description: 'target qq or group number' } @@ -19,10 +19,11 @@ export class SendMessageToSpecificGroupOrUserTool extends AbstractTool { } func = async function (opt, e) { - let { msg, target } = opt - target = isNaN(target) || !target - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(target.trim()) + let { msg, targetGroupIdOrQQNumber } = opt + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id + const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) let groupList = await Bot.getGroupList() try { diff --git a/utils/tools/SendMusicTool.js b/utils/tools/SendMusicTool.js index 8abbc29..ca5c9c7 100644 --- a/utils/tools/SendMusicTool.js +++ b/utils/tools/SendMusicTool.js @@ -20,9 +20,10 @@ export class SendMusicTool extends AbstractTool { func = async function (opts, e) { let { id, targetGroupIdOrQQNumber } = opts // 非法值则发送到当前群聊 + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.group_id - : parseInt(targetGroupIdOrQQNumber.trim()) + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) try { let group = await Bot.pickGroup(target) diff --git a/utils/tools/SendPictureTool.js b/utils/tools/SendPictureTool.js index df0d3c0..5e5befc 100644 --- a/utils/tools/SendPictureTool.js +++ b/utils/tools/SendPictureTool.js @@ -19,9 +19,10 @@ export class SendPictureTool extends AbstractTool { func = async function (opt, e) { let { urlOfPicture, targetGroupIdOrQQNumber } = opt + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(targetGroupIdOrQQNumber.trim()) + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) // 处理错误url和picture留空的情况 const urlRegex = /(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:((?:(?:[a-z0-9\u00a1-\u4dff\u9fd0-\uffff][a-z0-9\u00a1-\u4dff\u9fd0-\uffff_-]{0,62})?[a-z0-9\u00a1-\u4dff\u9fd0-\uffff]\.)+(?:[a-z\u00a1-\u4dff\u9fd0-\uffff]{2,}\.?))(?::\d{2,5})?)(?:\/[\w\u00a1-\u4dff\u9fd0-\uffff$-_.+!*'(),%]+)*(?:\?(?:[\w\u00a1-\u4dff\u9fd0-\uffff$-_.+!*(),%:@&=]|(?:[\[\]])|(?:[\u00a1-\u4dff\u9fd0-\uffff]))*)?(?:#(?:[\w\u00a1-\u4dff\u9fd0-\uffff$-_.+!*'(),;:@&=]|(?:[\[\]]))*)?\/?/i if (/https:\/\/example.com/.test(urlOfPicture) || !urlOfPicture || !urlRegex.test(urlOfPicture)) urlOfPicture = '' diff --git a/utils/tools/SendRPSTool.js b/utils/tools/SendRPSTool.js index 0681276..defb3b9 100644 --- a/utils/tools/SendRPSTool.js +++ b/utils/tools/SendRPSTool.js @@ -16,10 +16,10 @@ export class SendRPSTool extends AbstractTool { } func = async function (num, targetGroupIdOrQQNumber, e) { + const defaultTarget = e.isGroup ? e.group_id : e.sender.user_id const target = isNaN(targetGroupIdOrQQNumber) || !targetGroupIdOrQQNumber - ? e.isGroup ? e.group_id : e.sender.user_id - : parseInt(targetGroupIdOrQQNumber.trim()) - + ? defaultTarget + : parseInt(targetGroupIdOrQQNumber) === Bot.uin ? defaultTarget : parseInt(targetGroupIdOrQQNumber) let groupList = await Bot.getGroupList() if (groupList.get(target)) { let group = await Bot.pickGroup(target, true)