fix: merge tons of conflict

This commit is contained in:
ikechan8370 2023-07-01 15:55:07 +08:00
commit 7a8b30db14
50 changed files with 1791 additions and 828 deletions

View file

@ -7,10 +7,8 @@ import { ChatGPTAPI } from '../utils/openai/chatgpt-api.js'
import { BingAIClient } from '@waylaidwanderer/chatgpt-api'
import SydneyAIClient from '../utils/SydneyAIClient.js'
import { PoeClient } from '../utils/poe/index.js'
import AzureTTS, { supportConfigurations } from '../utils/tts/microsoft-azure.js'
import AzureTTS from '../utils/tts/microsoft-azure.js'
import VoiceVoxTTS from '../utils/tts/voicevox.js'
import { translate } from '../utils/translate.js'
import fs from 'fs'
import {
render,
renderUrl,
@ -27,24 +25,21 @@ import {
getUserReplySetting,
getImageOcrText,
getImg,
processList,
getMaxModelTokens, formatDate
getMaxModelTokens, formatDate, generateAudio
} from '../utils/common.js'
import { ChatGPTPuppeteer } from '../utils/browser.js'
import { KeyvFile } from 'keyv-file'
import { OfficialChatGPTClient } from '../utils/message.js'
import fetch from 'node-fetch'
import { deleteConversation, getConversations, getLatestMessageIdByConversationId } from '../utils/conversation.js'
import { convertSpeaker, generateAudio, speakers } from '../utils/tts.js'
import { convertSpeaker, speakers } from '../utils/tts.js'
import ChatGLMClient from '../utils/chatglm.js'
import { convertFaces } from '../utils/face.js'
import uploadRecord from '../utils/uploadRecord.js'
import { SlackClaudeClient } from '../utils/slack/slackClient.js'
import { getPromptByName } from '../utils/prompts.js'
import BingDrawClient from '../utils/BingDraw.js'
import XinghuoClient from '../utils/xinghuo/xinghuo.js'
import { JinyanTool } from '../utils/tools/JinyanTool.js'
import { SendMusicTool } from '../utils/tools/SendMusicTool.js'
import { SendVideoTool } from '../utils/tools/SendBilibiliTool.js'
import { KickOutTool } from '../utils/tools/KickOutTool.js'
import { EditCardTool } from '../utils/tools/EditCardTool.js'
@ -58,12 +53,19 @@ import { SerpIkechan8370Tool } from '../utils/tools/SerpIkechan8370Tool.js'
import { SendPictureTool } from '../utils/tools/SendPictureTool.js'
import { SerpImageTool } from '../utils/tools/SearchImageTool.js'
import { ImageCaptionTool } from '../utils/tools/ImageCaptionTool.js'
import { TTSTool } from '../utils/tools/TTSTool.js'
import { SendAudioMessageTool } from '../utils/tools/SendAudioMessageTool.js'
import { ProcessPictureTool } from '../utils/tools/ProcessPictureTool.js'
import { APTool } from '../utils/tools/APTool.js'
import { QueryGenshinTool } from '../utils/tools/QueryGenshinTool.js'
import { HandleMessageMsgTool } from '../utils/tools/HandleMessageMsgTool.js'
import {QueryUserinfoTool} from "../utils/tools/QueryUserinfoTool.js";
import { QueryUserinfoTool } from '../utils/tools/QueryUserinfoTool.js'
import { EliMovieTool } from '../utils/tools/EliMovieTool.js'
import { EliMusicTool } from '../utils/tools/EliMusicTool.js'
import { SendMusicTool } from '../utils/tools/SendMusicTool.js'
import { SendDiceTool } from '../utils/tools/SendDiceTool.js'
import { SendAvatarTool } from '../utils/tools/SendAvatarTool.js'
import { SendMessageToSpecificGroupOrUserTool } from '../utils/tools/SendMessageToSpecificGroupOrUserTool.js'
try {
await import('emoji-strip')
} catch (err) {
@ -283,6 +285,8 @@ export class chatgpt extends plugin {
return
}
let ats = e.message.filter(m => m.type === 'at')
const isAtMode = Config.toggleMode === 'at'
if (isAtMode) ats = ats.filter(item => item.qq !== Bot.uin)
if (ats.length === 0) {
if (use === 'api3') {
await redis.del(`CHATGPT:QQ_CONVERSATION:${e.sender.user_id}`)
@ -783,16 +787,37 @@ export class chatgpt extends plugin {
return false
}
// 黑白名单过滤对话
let [whitelist, blacklist] = processList(Config.whitelist, Config.blacklist)
let [whitelist, blacklist] = [Config.whitelist, Config.blacklist]
let chatPermission = false // 对话许可
if (whitelist.join('').length > 0) {
if (e.isGroup && !whitelist.includes(e.group_id.toString())) return false
const list = whitelist.filter(elem => elem.startsWith('^')).map(elem => elem.slice(1))
if (!list.includes(e.sender.user_id.toString())) return false
for (const item of whitelist) {
if (item.length > 11) {
const [group, qq] = item.split('^')
if (e.isGroup && group === e.group_id.toString() && qq === e.sender.user_id.toString()) {
chatPermission = true
break
}
} else if (item.startsWith('^') && item.slice(1) === e.sender.user_id.toString()) {
chatPermission = true
break
} else if (e.isGroup && !item.startsWith('^') && item === e.group_id.toString()) {
chatPermission = true
break
}
}
}
if (blacklist.join('').length > 0) {
if (e.isGroup && blacklist.includes(e.group_id.toString())) return false
const list = blacklist.filter(elem => elem.startsWith('^')).map(elem => elem.slice(1))
if (list.includes(e.sender.user_id.toString())) return false
// 当前用户有对话许可则不再判断黑名单
if (!chatPermission) {
if (blacklist.join('').length > 0) {
for (const item of blacklist) {
if (e.isGroup && !item.startsWith('^') && item === e.group_id.toString()) return false
if (item.startsWith('^') && item.slice(1) === e.sender.user_id.toString()) return false
if (item.length > 11) {
const [group, qq] = item.split('^')
if (e.isGroup && group === e.group_id.toString() && qq === e.sender.user_id.toString()) return false
}
}
}
}
let userSetting = await getUserReplySetting(this.e)
@ -1149,82 +1174,12 @@ export class chatgpt extends plugin {
this.reply(`建议的回复:\n${chatMessage.suggestedResponses}`)
}
}
let wav
if (Config.ttsMode === 'vits-uma-genshin-honkai' && Config.ttsSpace) {
if (Config.autoJapanese) {
try {
ttsResponse = await translate(ttsResponse, '日')
} catch (err) {
logger.error(err)
await this.reply(err.message + '\n将使用原始文本合成语音...')
}
}
try {
wav = await generateAudio(ttsResponse, speaker, '中日混合(中文用[ZH][ZH]包裹起来,日文用[JA][JA]包裹起来)')
} catch (err) {
logger.error(err)
await this.reply('合成语音发生错误~')
}
} else if (Config.ttsMode === 'azure' && Config.azureTTSKey) {
if (speaker !== '随机') {
let languagePrefix = AzureTTS.supportConfigurations.find(config => config.code === speaker).languageDetail.charAt(0)
languagePrefix = languagePrefix.startsWith('E') ? '英' : languagePrefix
ttsResponse = (await translate(ttsResponse, languagePrefix)).replace('\n', '')
} else {
let role, languagePrefix
role = AzureTTS.supportConfigurations[Math.floor(Math.random() * supportConfigurations.length)]
speaker = role.code
languagePrefix = role.languageDetail.charAt(0).startsWith('E') ? '英' : role.languageDetail.charAt(0)
ttsResponse = (await translate(ttsResponse, languagePrefix)).replace('\n', '')
if (role?.emotion) {
const keys = Object.keys(role.emotion)
emotion = keys[Math.floor(Math.random() * keys.length)]
}
logger.info('using speaker: ' + speaker)
logger.info('using language: ' + languagePrefix)
logger.info('using emotion: ' + emotion)
}
let ssml = AzureTTS.generateSsml(ttsResponse, {
speaker,
emotion,
emotionDegree
})
wav = await AzureTTS.generateAudio(ttsResponse, {
speaker
}, await ssml)
} else if (Config.ttsMode === 'voicevox' && Config.voicevoxSpace) {
ttsResponse = (await translate(ttsResponse, '日')).replace('\n', '')
wav = await VoiceVoxTTS.generateAudio(ttsResponse, {
speaker
})
} else if (!Config.ttsSpace && !Config.azureTTSKey && !Config.voicevoxSpace) {
await this.reply('你没有配置转语音API哦')
}
try {
try {
let sendable = await uploadRecord(wav, Config.ttsMode)
if (sendable) {
await e.reply(sendable)
} else {
// 如果合成失败尝试使用ffmpeg合成
await e.reply(segment.record(wav))
}
} catch (err) {
logger.error(err)
await e.reply(segment.record(wav))
}
} catch (err) {
logger.error(err)
const sendable = await generateAudio(this.e, ttsResponse, emotion, emotionDegree)
if (sendable) {
await this.reply(sendable)
} else {
await this.reply('合成语音发生错误~')
}
if (Config.ttsMode === 'azure' && Config.azureTTSKey) {
// 清理文件
try {
fs.unlinkSync(wav)
} catch (err) {
logger.warn(err)
}
}
} else if (userSetting.usePicture || (Config.autoUsePicture && response.length > Config.autoUsePictureThreshold)) {
// todo use next api of chatgpt to complete incomplete respoonse
try {
@ -1849,12 +1804,13 @@ export class chatgpt extends plugin {
chats.push(...chatHistory.reverse())
}
chats = chats.slice(0, Config.groupContextLength)
// 太多可能会干扰AI对自身qq号和用户qq的判断感觉gpt3.5也处理不了那么多信息
chats = chats > 50 ? 50 : chats
let mm = await e.group.getMemberMap()
chats.forEach(chat => {
let sender = mm.get(chat.sender.user_id)
chat.sender = sender
})
// console.log(chats)
opt.chats = chats
const namePlaceholder = '[name]'
const defaultBotName = 'ChatGPT'
@ -1872,8 +1828,7 @@ export class chatgpt extends plugin {
admin: 'group administrator'
}
if (chats) {
system += `There is the conversation history in the group, you must chat according to the conversation history context"
`
system += `There is the conversation history in the group, you must chat according to the conversation history context"`
system += chats
.map(chat => {
let sender = chat.sender || {}
@ -1891,6 +1846,7 @@ export class chatgpt extends plugin {
logger.warn('获取群聊聊天记录失败,本次对话不携带聊天记录', err)
}
}
// logger.info(system)
}
let opts = {
apiBaseUrl: Config.openAiBaseUrl,
@ -1949,45 +1905,58 @@ export class chatgpt extends plugin {
new WeatherTool(),
new SendPictureTool(),
new SendVideoTool(),
new SearchMusicTool(),
new SendMusicTool(),
new ImageCaptionTool(),
new SearchVideoTool(),
new SendAvatarTool(),
new SerpImageTool(),
new SearchMusicTool(),
new SendMusicTool(),
new SerpIkechan8370Tool(),
new SerpTool(),
new TTSTool(),
new SendAudioMessageTool(),
new ProcessPictureTool(),
new APTool(),
new QueryGenshinTool(),
new HandleMessageMsgTool(),
new QueryUserinfoTool()
new QueryUserinfoTool(),
new EliMusicTool(),
new EliMovieTool(),
new SendMessageToSpecificGroupOrUserTool(),
new SendDiceTool(),
new QueryGenshinTool()
]
// todo 3.0再重构tool的插拔和管理
let tools = [
// new SendAvatarTool(),
// new SendDiceTool(),
new SendAvatarTool(),
new SendDiceTool(),
new SendMessageToSpecificGroupOrUserTool(),
// new EditCardTool(),
new QueryStarRailTool(),
new QueryGenshinTool(),
new ProcessPictureTool(),
new WebsiteTool(),
// new JinyanTool(),
// new KickOutTool(),
new WeatherTool(),
new SendPictureTool(),
new TTSTool(),
new SendAudioMessageTool(),
new APTool(),
// new HandleMessageMsgTool(),
serpTool,
new QueryUserinfoTool()
]
try {
await import('../../avocado-plugin/apps/avocado.js')
tools.push(...[new EliMusicTool(), new EliMovieTool()])
} catch (err) {
tools.push(...[new SendMusicTool(), new SearchMusicTool()])
logger.mark(logger.green('【ChatGPT-Plugin】插件avocado-plugin未安装') + ',安装后可查看最近热映电影与体验可玩性更高的点歌工具。\n可前往 https://github.com/Qz-Sean/avocado-plugin 获取')
}
if (e.isGroup) {
let botInfo = await Bot.getGroupMemberInfo(e.group_id, Bot.uin, true)
if (botInfo.role !== 'member') {
// 管理员才给这些工具
tools.push(...[new EditCardTool(), new JinyanTool(), new KickOutTool(), new HandleMessageMsgTool()])
// 用于撤回和加精的id
if (e.source?.seq) {
let source = (await e.group.getChatHistory(e.source?.seq, 1)).pop()
option.systemMessage += `\nthe last message is replying to ${source.message_id}"\n`
@ -2025,8 +1994,7 @@ export class chatgpt extends plugin {
tools.push(new SerpImageTool())
tools.push(...[new SearchVideoTool(),
new SendVideoTool(),
new SearchMusicTool(),
new SendMusicTool()])
new EliMusicTool()])
}
let funcMap = {}
let fullFuncMap = {}
@ -2053,6 +2021,7 @@ export class chatgpt extends plugin {
while (msg.functionCall) {
let { name, arguments: args } = msg.functionCall
args = JSON.parse(args)
// 感觉换成targetGroupIdOrUserQQNumber这种表意比较清楚的变量名效果会好一丢丢
if (!args.groupId) {
args.groupId = e.group_id + '' || e.sender.user_id + ''
}
@ -2061,14 +2030,6 @@ export class chatgpt extends plugin {
} catch (err) {
args.groupId = e.group_id + '' || e.sender.user_id + ''
}
if (!args.qq) {
args.qq = e.sender.user_id + ''
}
try {
parseInt(args.qq)
} catch (err) {
args.qq = e.sender.user_id + ''
}
let functionResult = await fullFuncMap[name].exec(Object.assign({ isAdmin, sender }, args), e)
logger.mark(`function ${name} execution result: ${functionResult}`)
option.parentMessageId = msg.id