mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 13:27:08 +00:00
Merge branch 'v2' of github.com:ikechan8370/chatgpt-plugin into v2
This commit is contained in:
commit
9c73c99b65
34 changed files with 1779 additions and 643 deletions
104
apps/chat.js
104
apps/chat.js
|
|
@ -81,6 +81,7 @@ import { getChatHistoryGroup } from '../utils/chat.js'
|
|||
import { CustomGoogleGeminiClient } from '../client/CustomGoogleGeminiClient.js'
|
||||
import { resizeAndCropImage } from '../utils/dalle.js'
|
||||
import fs from 'fs'
|
||||
import { ChatGLM4Client } from '../client/ChatGLM4Client.js'
|
||||
|
||||
const roleMap = {
|
||||
owner: 'group owner',
|
||||
|
|
@ -106,8 +107,8 @@ try {
|
|||
let version = Config.version
|
||||
let proxy = getProxy()
|
||||
|
||||
const originalValues = ['星火', '通义千问', '克劳德', '克劳德2', '必应', 'api', 'API', 'api3', 'API3', 'glm', '巴德']
|
||||
const correspondingValues = ['xh', 'qwen', 'claude', 'claude2', 'bing', 'api', 'api', 'api3', 'api3', 'chatglm', 'bard']
|
||||
const originalValues = ['星火', '通义千问', '克劳德', '克劳德2', '必应', 'api', 'API', 'api3', 'API3', 'glm', '巴德', '双子星', '双子座', '智谱']
|
||||
const correspondingValues = ['xh', 'qwen', 'claude', 'claude2', 'bing', 'api', 'api', 'api3', 'api3', 'chatglm', 'bard', 'gemini', 'gemini', 'chatglm4']
|
||||
/**
|
||||
* 每个对话保留的时长。单个对话内ai是保留上下文的。超时后销毁对话,再次对话创建新的对话。
|
||||
* 单位:秒
|
||||
|
|
@ -133,6 +134,7 @@ const newFetch = (url, options = {}) => {
|
|||
export class chatgpt extends plugin {
|
||||
constructor () {
|
||||
let toggleMode = Config.toggleMode
|
||||
let apiStream = Config.apiStream
|
||||
super({
|
||||
/** 功能名称 */
|
||||
name: 'ChatGpt 对话',
|
||||
|
|
@ -196,6 +198,12 @@ export class chatgpt extends plugin {
|
|||
reg: '^#星火(搜索|查找)助手',
|
||||
fnc: 'searchxhBot'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#glm4[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'glm4'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#qwen[sS]*',
|
||||
|
|
@ -221,11 +229,11 @@ export class chatgpt extends plugin {
|
|||
permission: 'master'
|
||||
},
|
||||
{
|
||||
reg: '^#(chatgpt|星火|通义千问|克劳德|克劳德2|必应|api|API|api3|API3|glm|巴德)?(结束|新开|摧毁|毁灭|完结)对话([sS]*)',
|
||||
reg: `^#?(${originalValues.join('|')})?(结束|新开|摧毁|毁灭|完结)对话([sS]*)$`,
|
||||
fnc: 'destroyConversations'
|
||||
},
|
||||
{
|
||||
reg: '^#(chatgpt|星火|通义千问|克劳德|克劳德2|必应|api|API|api3|API3|glm|巴德)?(结束|新开|摧毁|毁灭|完结)全部对话$',
|
||||
reg: `^#?(${originalValues.join('|')})?(结束|新开|摧毁|毁灭|完结)全部对话$`,
|
||||
fnc: 'endAllConversations',
|
||||
permission: 'master'
|
||||
},
|
||||
|
|
@ -284,6 +292,7 @@ export class chatgpt extends plugin {
|
|||
]
|
||||
})
|
||||
this.toggleMode = toggleMode
|
||||
this.apiStream = apiStream
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -358,7 +367,7 @@ export class chatgpt extends plugin {
|
|||
if (use === 'api3') {
|
||||
await redis.del(`CHATGPT:QQ_CONVERSATION:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
|
||||
await this.reply('已退出当前对话,该对话仍然保留。请@我进行聊天以开启新的对话', true)
|
||||
} else if (use === 'bing' && (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom')) {
|
||||
} else if (use === 'bing') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`)
|
||||
if (!c) {
|
||||
await this.reply('当前没有开启对话', true)
|
||||
|
|
@ -419,6 +428,14 @@ export class chatgpt extends plugin {
|
|||
await redis.del(`CHATGPT:CONVERSATIONS_GEMINI:${e.sender.user_id}`)
|
||||
await this.reply('已结束当前对话,请@我进行聊天以开启新的对话', true)
|
||||
}
|
||||
} else if (use === 'chatglm4') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_CHATGLM4:${e.sender.user_id}`)
|
||||
if (!c) {
|
||||
await this.reply('当前没有开启对话', true)
|
||||
} else {
|
||||
await redis.del(`CHATGPT:CONVERSATIONS_CHATGLM4:${e.sender.user_id}`)
|
||||
await this.reply('已结束当前对话,请@我进行聊天以开启新的对话', true)
|
||||
}
|
||||
} else if (use === 'bing') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${e.sender.user_id}`)
|
||||
if (!c) {
|
||||
|
|
@ -443,7 +460,7 @@ export class chatgpt extends plugin {
|
|||
if (use === 'api3') {
|
||||
await redis.del(`CHATGPT:QQ_CONVERSATION:${qq}`)
|
||||
await this.reply(`${atUser}已退出TA当前的对话,TA仍可以@我进行聊天以开启新的对话`, true)
|
||||
} else if (use === 'bing' && (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom')) {
|
||||
} else if (use === 'bing') {
|
||||
const conversation = {
|
||||
store: new KeyvFile({ filename: 'cache.json' }),
|
||||
namespace: Config.toneStyle
|
||||
|
|
@ -496,6 +513,14 @@ export class chatgpt extends plugin {
|
|||
await redis.del(`CHATGPT:CONVERSATIONS_GEMINI:${qq}`)
|
||||
await this.reply(`已结束${atUser}的对话,TA仍可以@我进行聊天以开启新的对话`, true)
|
||||
}
|
||||
} else if (use === 'chatglm4') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_CHATGLM4:${qq}`)
|
||||
if (!c) {
|
||||
await this.reply(`当前${atUser}没有开启对话`, true)
|
||||
} else {
|
||||
await redis.del(`CHATGPT:CONVERSATIONS_CHATGLM4:${qq}`)
|
||||
await this.reply(`已结束${atUser}的对话,TA仍可以@我进行聊天以开启新的对话`, true)
|
||||
}
|
||||
} else if (use === 'bing') {
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${qq}`)
|
||||
if (!c) {
|
||||
|
|
@ -639,6 +664,18 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
break
|
||||
}
|
||||
case 'chatglm4': {
|
||||
let qcs = await redis.keys('CHATGPT:CONVERSATIONS_CHATGLM4:*')
|
||||
for (let i = 0; i < qcs.length; i++) {
|
||||
await redis.del(qcs[i])
|
||||
// todo clean last message id
|
||||
if (Config.debug) {
|
||||
logger.info('delete chatglm4 conversation bind: ' + qcs[i])
|
||||
}
|
||||
deleted++
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
await this.reply(`结束了${deleted}个用户的对话。`, true)
|
||||
}
|
||||
|
|
@ -972,24 +1009,8 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
let userSetting = await getUserReplySetting(this.e)
|
||||
let useTTS = !!userSetting.useTTS
|
||||
let speaker
|
||||
if (Config.ttsMode === 'vits-uma-genshin-honkai') {
|
||||
speaker = convertSpeaker(userSetting.ttsRole || Config.defaultTTSRole)
|
||||
} else if (Config.ttsMode === 'azure') {
|
||||
speaker = userSetting.ttsRoleAzure || Config.azureTTSSpeaker
|
||||
} else if (Config.ttsMode === 'voicevox') {
|
||||
speaker = userSetting.ttsRoleVoiceVox || Config.voicevoxTTSSpeaker
|
||||
}
|
||||
// 每个回答可以指定
|
||||
let trySplit = prompt.split('回答:')
|
||||
if (trySplit.length > 1 && speakers.indexOf(convertSpeaker(trySplit[0])) > -1) {
|
||||
useTTS = true
|
||||
speaker = convertSpeaker(trySplit[0])
|
||||
prompt = trySplit[1]
|
||||
}
|
||||
const isImg = await getImg(e)
|
||||
if (Config.imgOcr && !!isImg) {
|
||||
let imgOcrText = await getImageOcrText(e)
|
||||
|
|
@ -1138,6 +1159,10 @@ export class chatgpt extends plugin {
|
|||
key = `CHATGPT:CONVERSATIONS_GEMINI:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`
|
||||
break
|
||||
}
|
||||
case 'chatglm4': {
|
||||
key = `CHATGPT:CONVERSATIONS_CHATGLM4:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`
|
||||
break
|
||||
}
|
||||
}
|
||||
let ctime = new Date()
|
||||
previousConversation = (key ? await redis.get(key) : null) || JSON.stringify({
|
||||
|
|
@ -1177,6 +1202,7 @@ export class chatgpt extends plugin {
|
|||
await e.reply([element.tag, segment.image(element.url)])
|
||||
})
|
||||
}
|
||||
// chatglm4图片,调整至sendMessage中处理
|
||||
if (use === 'api' && !chatMessage) {
|
||||
// 字数超限直接返回
|
||||
return false
|
||||
|
|
@ -1190,11 +1216,7 @@ export class chatgpt extends plugin {
|
|||
previousConversation.invocationId = chatMessage.invocationId
|
||||
previousConversation.parentMessageId = chatMessage.parentMessageId
|
||||
previousConversation.conversationSignature = chatMessage.conversationSignature
|
||||
if (Config.toneStyle !== 'Sydney' && Config.toneStyle !== 'Custom') {
|
||||
previousConversation.bingToken = chatMessage.bingToken
|
||||
} else {
|
||||
previousConversation.bingToken = ''
|
||||
}
|
||||
previousConversation.bingToken = ''
|
||||
} else if (chatMessage.id) {
|
||||
previousConversation.parentMessageId = chatMessage.id
|
||||
} else if (chatMessage.message) {
|
||||
|
|
@ -1457,7 +1479,11 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
|
||||
async qwen (e) {
|
||||
return await this.otherMode(e, 'gemini')
|
||||
return await this.otherMode(e, 'qwen')
|
||||
}
|
||||
|
||||
async glm4 (e) {
|
||||
return await this.otherMode(e, 'chatglm4')
|
||||
}
|
||||
|
||||
async gemini (e) {
|
||||
|
|
@ -1563,7 +1589,7 @@ export class chatgpt extends plugin {
|
|||
opt.toneStyle = Config.toneStyle
|
||||
// 如果当前没有开启对话或者当前是Sydney模式、Custom模式,则本次对话携带拓展资料
|
||||
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${e.sender.user_id}`)
|
||||
if (!c || Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') {
|
||||
if (!c) {
|
||||
opt.context = useCast?.bing_resource || Config.sydneyContext
|
||||
}
|
||||
// 重新拿存储的token,因为可能之前有过期的被删了
|
||||
|
|
@ -1916,7 +1942,8 @@ export class chatgpt extends plugin {
|
|||
let response = await client.sendMessage(prompt, {
|
||||
e,
|
||||
chatId: conversation?.conversationId,
|
||||
image: image ? image[0] : undefined
|
||||
image: image ? image[0] : undefined,
|
||||
system: Config.xhPrompt
|
||||
})
|
||||
return response
|
||||
} else if (use === 'azure') {
|
||||
|
|
@ -2159,6 +2186,15 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
option.system = system
|
||||
return await client.sendMessage(prompt, option)
|
||||
} else if (use === 'chatglm4') {
|
||||
const client = new ChatGLM4Client({
|
||||
refreshToken: Config.chatglmRefreshToken
|
||||
})
|
||||
let resp = await client.sendMessage(prompt, conversation)
|
||||
if (resp.image) {
|
||||
e.reply(segment.image(resp.image), true)
|
||||
}
|
||||
return resp
|
||||
} else {
|
||||
// openai api
|
||||
let completionParams = {}
|
||||
|
|
@ -2239,7 +2275,7 @@ export class chatgpt extends plugin {
|
|||
let option = {
|
||||
timeoutMs: 600000,
|
||||
completionParams,
|
||||
stream: true,
|
||||
stream: this.apiStream,
|
||||
onProgress: (data) => {
|
||||
if (Config.debug) {
|
||||
logger.info(data?.text || data.functionCall || data)
|
||||
|
|
@ -2790,12 +2826,6 @@ async function getAvailableBingToken (conversation, throttled = []) {
|
|||
allThrottled
|
||||
}
|
||||
}
|
||||
if (Config.toneStyle != 'Sydney' && Config.toneStyle != 'Custom') {
|
||||
// bing 下,需要保证同一对话使用同一账号的token
|
||||
if (bingTokens.findIndex(element => element.Token === conversation.bingToken) > -1) {
|
||||
bingToken = conversation.bingToken
|
||||
}
|
||||
}
|
||||
// 记录使用情况
|
||||
const index = bingTokens.findIndex(element => element.Token === bingToken)
|
||||
bingTokens[index].Usage += 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue