feat: 通过降级messageType手段复活限流的账户

This commit is contained in:
ikechan8370 2023-04-02 12:08:48 +08:00
parent 14b4d3cdf4
commit 95a4d7a69c
3 changed files with 69 additions and 27 deletions

View file

@ -1006,25 +1006,8 @@ export class chatgpt extends plugin {
return await this.chatgptBrowserBased(prompt, conversation)
}
case 'bing': {
let bingToken = await redis.get('CHATGPT:BING_TOKEN')
if (!bingToken) {
throw new Error('未绑定Bing Cookie请使用#chatgpt设置必应token命令绑定Bing Cookie')
}
const bingTokens = bingToken.split('|')
// 负载均衡
if (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') {
// sydney下不需要保证同一token
const select = Math.floor(Math.random() * bingTokens.length)
bingToken = bingTokens[select]
} else {
// bing 下需要保证同一对话使用同一账号的token
if (!conversation.bingToken) {
const select = Math.floor(Math.random() * bingTokens.length)
bingToken = bingTokens[select]
} else if (bingTokens.indexOf(conversation.bingToken) > -1) {
bingToken = conversation.bingToken
}
}
let throttledTokens = []
let { bingToken, allThrottled } = await getAvailableBingToken(conversation, throttledTokens)
let cookies
if (bingToken?.indexOf('=') > -1) {
cookies = bingToken
@ -1064,11 +1047,21 @@ export class chatgpt extends plugin {
let reply = ''
let retry = 3
let errorMessage = ''
do {
let abtrs = await getAvailableBingToken(conversation, throttledTokens)
bingToken = abtrs.bingToken
allThrottled = abtrs.allThrottled
if (bingToken?.indexOf('=') > -1) {
cookies = bingToken
}
bingAIClient.opts.userToken = bingToken
bingAIClient.opts.cookies = cookies
try {
let opt = _.cloneDeep(conversation) || {}
opt.toneStyle = Config.toneStyle
opt.context = Config.sydneyContext
opt.messageType = allThrottled ? 'Chat' : 'SearchQuery'
if (Config.enableGroupContext && e.isGroup) {
try {
opt.groupId = e.group_id
@ -1119,8 +1112,13 @@ export class chatgpt extends plugin {
break
} catch (error) {
const message = error?.message || error?.data?.message || error || '出错了'
retry--
errorMessage = message === 'Timed out waiting for response. Try enabling debug mode to see more information.' ? (reply ? `${reply}\n不行了,我的大脑过载了,处理不过来了!` : '必应的小脑瓜不好使了,不知道怎么回答!') : message
if (message.indexOf('限流') > -1) {
throttledTokens.push(bingToken)
// 不减次数
} else {
retry--
errorMessage = message === 'Timed out waiting for response. Try enabling debug mode to see more information.' ? (reply ? `${reply}\n不行了,我的大脑过载了,处理不过来了!` : '必应的小脑瓜不好使了,不知道怎么回答!') : message
}
}
} while (retry > 0)
if (errorMessage) {
@ -1139,7 +1137,7 @@ export class chatgpt extends plugin {
invocationId: response.invocationId,
conversationSignature: response.conversationSignature,
parentMessageId: response.apology ? conversation.parentMessageId : response.messageId,
bingToken: bingToken
bingToken
}
}
}
@ -1368,3 +1366,39 @@ export class chatgpt extends plugin {
return await this.chatGPTApi.sendMessage(prompt, sendMessageOption)
}
}
async function getAvailableBingToken (conversation, throttled = []) {
let allThrottled = false
let bingToken = await redis.get('CHATGPT:BING_TOKEN')
if (!bingToken) {
throw new Error('未绑定Bing Cookie请使用#chatgpt设置必应token命令绑定Bing Cookie')
}
const bingTokens = bingToken.split('|')
// 负载均衡
if (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') {
// sydney下不需要保证同一token
let notThrottled = bingTokens.filter(t => throttled.indexOf(t) === -1)
if (notThrottled.length > 0) {
bingToken = notThrottled[0]
} else {
// 全都被限流了,随便找一个算了
allThrottled = true
const select = Math.floor(Math.random() * bingTokens.length)
bingToken = bingTokens[select]
}
// const select = Math.floor(Math.random() * bingTokens.length)
// bingToken = bingTokens[select]
} else {
// bing 下需要保证同一对话使用同一账号的token
if (!conversation.bingToken) {
const select = Math.floor(Math.random() * bingTokens.length)
bingToken = bingTokens[select]
} else if (bingTokens.indexOf(conversation.bingToken) > -1) {
bingToken = conversation.bingToken
}
}
return {
bingToken,
allThrottled
}
}

View file

@ -217,8 +217,12 @@ export default class SydneyAIClient {
abortController = new AbortController(),
timeout = Config.defaultTimeoutMs,
firstMessageTimeout = Config.sydneyFirstMessageTimeout,
groupId, nickname, qq, groupName, chats, botName, masterName
groupId, nickname, qq, groupName, chats, botName, masterName,
messageType = 'SearchQuery'
} = opts
if (messageType === 'Chat') {
logger.warn('该Bing账户token已被限流降级至使用非搜索模式。本次对话AI将无法使用Bing搜索返回的内容')
}
if (typeof onProgress !== 'function') {
onProgress = () => {}
}
@ -382,8 +386,8 @@ export default class SydneyAIClient {
author: 'user',
inputMethod: 'Keyboard',
text: message,
// messageType: 'Chat'
messageType: 'SearchQuery'
messageType
// messageType: 'SearchQuery'
},
conversationSignature,
participant: {
@ -621,6 +625,10 @@ export default class SydneyAIClient {
if (event.item?.result) {
if (event.item?.result?.exception?.indexOf('maximum context length') > -1) {
reject('对话长度太长啦超出8193token请结束对话重新开始')
} else if (event.item?.result.value === 'Throttled') {
reject('该账户的SERP请求已被限流')
logger.warn('该账户的SERP请求已被限流')
logger.warn(JSON.stringify(event.item?.result))
} else {
reject(`${event.item?.result.value}\n${event.item?.result.error}\n${event.item?.result.exception}`)
}
@ -717,7 +725,7 @@ export default class SydneyAIClient {
conversationExpiryTime,
response: reply.text,
details: reply,
apology: Config.sydneyApologyIgnored && apology
apology: Config.sydneyApologyIgnored && apology,
}
} catch (err) {
await this.conversationsCache.set(conversationKey, conversation)

View file

@ -78,7 +78,7 @@ const defaultConfig = {
maxNumUserMessagesInConversation: 20,
sydneyApologyIgnored: true,
enforceMaster: false,
version: 'v2.4.10'
version: 'v2.4.11'
}
const _path = process.cwd()
let config = {}