mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 13:27:08 +00:00
fix: merge tons of conflict
This commit is contained in:
commit
7a8b30db14
50 changed files with 1791 additions and 828 deletions
189
apps/chat.js
189
apps/chat.js
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue