mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-17 13:57:10 +00:00
Merge branch 'ikechan8370:v2' into v2
This commit is contained in:
commit
53ee6bd9d6
2 changed files with 108 additions and 89 deletions
60
apps/chat.js
60
apps/chat.js
|
|
@ -1703,40 +1703,44 @@ export class chatgpt extends plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if (message && typeof message === 'string' && message.indexOf('限流') > -1) {
|
if (message && typeof message === 'string' && message.indexOf('限流') > -1) {
|
||||||
throttledTokens.push(bingToken)
|
throttledTokens.push(bingToken)
|
||||||
let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS'))
|
let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS'))
|
||||||
const badBingToken = bingTokens.findIndex(element => element.Token === bingToken)
|
const badBingToken = bingTokens.findIndex(element => element.Token === bingToken)
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const hours = now.getHours()
|
const hours = now.getHours()
|
||||||
now.setHours(hours + 6)
|
now.setHours(hours + 6)
|
||||||
bingTokens[badBingToken].State = '受限'
|
bingTokens[badBingToken].State = '受限'
|
||||||
bingTokens[badBingToken].DisactivationTime = now
|
bingTokens[badBingToken].DisactivationTime = now
|
||||||
await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens))
|
await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens))
|
||||||
// 不减次数
|
// 不减次数
|
||||||
} else if (message && typeof message === 'string' && message.indexOf('UnauthorizedRequest') > -1) {
|
} else if (message && typeof message === 'string' && message.indexOf('UnauthorizedRequest') > -1) {
|
||||||
// token过期了
|
// token过期了
|
||||||
let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS'))
|
let bingTokens = JSON.parse(await redis.get('CHATGPT:BING_TOKENS'))
|
||||||
const badBingToken = bingTokens.findIndex(element => element.Token === bingToken)
|
const badBingToken = bingTokens.findIndex(element => element.Token === bingToken)
|
||||||
// 可能是微软抽风,给三次机会
|
if (badBingToken > 0) {
|
||||||
if (bingTokens[badBingToken].exception) {
|
// 可能是微软抽风,给三次机会
|
||||||
if (bingTokens[badBingToken].exception <= 3) {
|
if (bingTokens[badBingToken]?.exception) {
|
||||||
bingTokens[badBingToken].exception += 1
|
if (bingTokens[badBingToken].exception <= 3) {
|
||||||
|
bingTokens[badBingToken].exception += 1
|
||||||
|
} else {
|
||||||
|
bingTokens[badBingToken].exception = 0
|
||||||
|
bingTokens[badBingToken].State = '过期'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bingTokens[badBingToken].exception = 1
|
||||||
|
}
|
||||||
|
await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens))
|
||||||
} else {
|
} else {
|
||||||
bingTokens[badBingToken].exception = 0
|
retry = retry - 1
|
||||||
bingTokens[badBingToken].State = '过期'
|
|
||||||
}
|
}
|
||||||
} else {
|
errorMessage = 'UnauthorizedRequest:必应token不正确或已过期'
|
||||||
bingTokens[badBingToken].exception = 1
|
|
||||||
}
|
|
||||||
await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens))
|
|
||||||
errorMessage = 'UnauthorizedRequest:必应token不正确或已过期'
|
|
||||||
// logger.warn(`token${bingToken}疑似不存在或已过期,再试试`)
|
// logger.warn(`token${bingToken}疑似不存在或已过期,再试试`)
|
||||||
// retry = retry - 1
|
// retry = retry - 1
|
||||||
} else {
|
} else {
|
||||||
retry--
|
retry--
|
||||||
errorMessage = message === 'Timed out waiting for response. Try enabling debug mode to see more information.' ? (reply ? `${reply}\n不行了,我的大脑过载了,处理不过来了!` : '必应的小脑瓜不好使了,不知道怎么回答!') : message
|
errorMessage = message === 'Timed out waiting for response. Try enabling debug mode to see more information.' ? (reply ? `${reply}\n不行了,我的大脑过载了,处理不过来了!` : '必应的小脑瓜不好使了,不知道怎么回答!') : message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (retry > 0)
|
} while (retry > 0)
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ export default class SydneyAIClient {
|
||||||
this.opts.host = 'https://edgeservices.bing.com/edgesvc'
|
this.opts.host = 'https://edgeservices.bing.com/edgesvc'
|
||||||
}
|
}
|
||||||
logger.mark('使用host:' + this.opts.host)
|
logger.mark('使用host:' + this.opts.host)
|
||||||
let response = await fetch(`${this.opts.host}/turing/conversation/create`, fetchOptions)
|
let response = await fetch(`${this.opts.host}/turing/conversation/create?bundleVersion=1.1055.6`, fetchOptions)
|
||||||
let text = await response.text()
|
let text = await response.text()
|
||||||
let retry = 10
|
let retry = 10
|
||||||
while (retry >= 0 && response.status === 200 && !text) {
|
while (retry >= 0 && response.status === 200 && !text) {
|
||||||
|
|
@ -115,7 +115,11 @@ export default class SydneyAIClient {
|
||||||
throw new Error('创建sydney对话失败: status code: ' + response.status + response.statusText)
|
throw new Error('创建sydney对话失败: status code: ' + response.status + response.statusText)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return JSON.parse(text)
|
let r = JSON.parse(text)
|
||||||
|
if (!r.conversationSignature) {
|
||||||
|
r.encryptedconversationsignature = response.headers.get('x-sydney-encryptedconversationsignature')
|
||||||
|
}
|
||||||
|
return r
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('创建sydney对话失败: status code: ' + response.status + response.statusText)
|
logger.error('创建sydney对话失败: status code: ' + response.status + response.statusText)
|
||||||
logger.error(text)
|
logger.error(text)
|
||||||
|
|
@ -123,7 +127,7 @@ export default class SydneyAIClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createWebSocketConnection () {
|
async createWebSocketConnection (encryptedconversationsignature = '') {
|
||||||
await this.initCache()
|
await this.initCache()
|
||||||
// let WebSocket = await getWebSocket()
|
// let WebSocket = await getWebSocket()
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -136,7 +140,11 @@ export default class SydneyAIClient {
|
||||||
sydneyHost = Config.sydneyReverseProxy.replace('https://', 'wss://').replace('http://', 'ws://')
|
sydneyHost = Config.sydneyReverseProxy.replace('https://', 'wss://').replace('http://', 'ws://')
|
||||||
}
|
}
|
||||||
logger.mark(`use sydney websocket host: ${sydneyHost}`)
|
logger.mark(`use sydney websocket host: ${sydneyHost}`)
|
||||||
let ws = new WebSocket(sydneyHost + '/sydney/ChatHub', undefined, { agent, origin: 'https://edgeservices.bing.com' })
|
let host = sydneyHost + '/sydney/ChatHub'
|
||||||
|
if (encryptedconversationsignature) {
|
||||||
|
host += `?sec_access_token=${encodeURIComponent(encryptedconversationsignature)}`
|
||||||
|
}
|
||||||
|
let ws = new WebSocket(host, undefined, { agent, origin: 'https://edgeservices.bing.com' })
|
||||||
ws.on('error', (err) => {
|
ws.on('error', (err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
reject(err)
|
reject(err)
|
||||||
|
|
@ -219,6 +227,7 @@ export default class SydneyAIClient {
|
||||||
// if (messageType === 'Chat') {
|
// if (messageType === 'Chat') {
|
||||||
// logger.warn('该Bing账户token已被限流,降级至使用非搜索模式。本次对话AI将无法使用Bing搜索返回的内容')
|
// logger.warn('该Bing账户token已被限流,降级至使用非搜索模式。本次对话AI将无法使用Bing搜索返回的内容')
|
||||||
// }
|
// }
|
||||||
|
let encryptedconversationsignature = ''
|
||||||
if (typeof onProgress !== 'function') {
|
if (typeof onProgress !== 'function') {
|
||||||
onProgress = () => { }
|
onProgress = () => { }
|
||||||
}
|
}
|
||||||
|
|
@ -231,7 +240,7 @@ export default class SydneyAIClient {
|
||||||
if (createNewConversationResponse.result?.value === 'UnauthorizedRequest') {
|
if (createNewConversationResponse.result?.value === 'UnauthorizedRequest') {
|
||||||
throw new Error(`UnauthorizedRequest: ${createNewConversationResponse.result.message}`)
|
throw new Error(`UnauthorizedRequest: ${createNewConversationResponse.result.message}`)
|
||||||
}
|
}
|
||||||
if (!createNewConversationResponse.conversationSignature || !createNewConversationResponse.conversationId || !createNewConversationResponse.clientId) {
|
if (!createNewConversationResponse.conversationId || !createNewConversationResponse.clientId) {
|
||||||
const resultValue = createNewConversationResponse.result?.value
|
const resultValue = createNewConversationResponse.result?.value
|
||||||
if (resultValue) {
|
if (resultValue) {
|
||||||
throw new Error(`${resultValue}: ${createNewConversationResponse.result.message}`)
|
throw new Error(`${resultValue}: ${createNewConversationResponse.result.message}`)
|
||||||
|
|
@ -241,7 +250,8 @@ export default class SydneyAIClient {
|
||||||
({
|
({
|
||||||
conversationSignature,
|
conversationSignature,
|
||||||
conversationId,
|
conversationId,
|
||||||
clientId
|
clientId,
|
||||||
|
encryptedconversationsignature
|
||||||
} = createNewConversationResponse)
|
} = createNewConversationResponse)
|
||||||
}
|
}
|
||||||
let pureSydney = Config.toneStyle === 'Sydney'
|
let pureSydney = Config.toneStyle === 'Sydney'
|
||||||
|
|
@ -331,7 +341,7 @@ export default class SydneyAIClient {
|
||||||
role: 'User',
|
role: 'User',
|
||||||
message
|
message
|
||||||
}
|
}
|
||||||
const ws = await this.createWebSocketConnection()
|
const ws = await this.createWebSocketConnection(encryptedconversationsignature)
|
||||||
if (Config.debug) {
|
if (Config.debug) {
|
||||||
logger.mark('sydney websocket constructed successful')
|
logger.mark('sydney websocket constructed successful')
|
||||||
}
|
}
|
||||||
|
|
@ -361,62 +371,67 @@ export default class SydneyAIClient {
|
||||||
let maxConv = Config.maxNumUserMessagesInConversation
|
let maxConv = Config.maxNumUserMessagesInConversation
|
||||||
const currentDate = moment().format('YYYY-MM-DDTHH:mm:ssZ')
|
const currentDate = moment().format('YYYY-MM-DDTHH:mm:ssZ')
|
||||||
const imageDate = await this.kblobImage(opts.imageUrl)
|
const imageDate = await this.kblobImage(opts.imageUrl)
|
||||||
|
let argument0 = {
|
||||||
|
source: 'cib',
|
||||||
|
optionsSets,
|
||||||
|
allowedMessageTypes: ['ActionRequest', 'Chat', 'Context',
|
||||||
|
// 'InternalSearchQuery', 'InternalSearchResult', 'Disengaged', 'InternalLoaderMessage', 'Progress', 'RenderCardRequest', 'AdsQuery',
|
||||||
|
'SemanticSerp', 'GenerateContentQuery', 'SearchQuery'],
|
||||||
|
sliceIds: [
|
||||||
|
|
||||||
|
],
|
||||||
|
requestId: crypto.randomUUID(),
|
||||||
|
traceId: genRanHex(32),
|
||||||
|
scenario: 'Underside',
|
||||||
|
verbosity: 'verbose',
|
||||||
|
isStartOfSession: invocationId === 0,
|
||||||
|
message: {
|
||||||
|
locale: 'zh-CN',
|
||||||
|
market: 'zh-CN',
|
||||||
|
region: 'WW',
|
||||||
|
location: 'lat:47.639557;long:-122.128159;re=1000m;',
|
||||||
|
locationHints: [
|
||||||
|
{
|
||||||
|
country: 'Macedonia',
|
||||||
|
state: 'Centar',
|
||||||
|
city: 'Skopje',
|
||||||
|
zipcode: '1004',
|
||||||
|
timezoneoffset: 1,
|
||||||
|
countryConfidence: 8,
|
||||||
|
cityConfidence: 5,
|
||||||
|
Center: {
|
||||||
|
Latitude: 41.9961,
|
||||||
|
Longitude: 21.4317
|
||||||
|
},
|
||||||
|
RegionType: 2,
|
||||||
|
SourceType: 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
author: 'user',
|
||||||
|
inputMethod: 'Keyboard',
|
||||||
|
imageUrl: imageDate.blobId ? `https://www.bing.com/images/blob?bcid=${imageDate.blobId}` : undefined,
|
||||||
|
originalImageUrl: imageDate.processedBlobId ? `https://www.bing.com/images/blob?bcid=${imageDate.processedBlobId}` : undefined,
|
||||||
|
text: message,
|
||||||
|
messageType,
|
||||||
|
userIpAddress: await generateRandomIP(),
|
||||||
|
timestamp: currentDate
|
||||||
|
// messageType: 'SearchQuery'
|
||||||
|
},
|
||||||
|
tone: 'Creative',
|
||||||
|
conversationSignature,
|
||||||
|
participant: {
|
||||||
|
id: clientId
|
||||||
|
},
|
||||||
|
spokenTextMode: 'None',
|
||||||
|
conversationId,
|
||||||
|
previousMessages
|
||||||
|
}
|
||||||
|
if (encryptedconversationsignature) {
|
||||||
|
delete argument0.conversationSignature
|
||||||
|
}
|
||||||
const obj = {
|
const obj = {
|
||||||
arguments: [
|
arguments: [
|
||||||
{
|
argument0
|
||||||
source: 'cib',
|
|
||||||
optionsSets,
|
|
||||||
allowedMessageTypes: ['ActionRequest', 'Chat', 'Context',
|
|
||||||
// 'InternalSearchQuery', 'InternalSearchResult', 'Disengaged', 'InternalLoaderMessage', 'Progress', 'RenderCardRequest', 'AdsQuery',
|
|
||||||
'SemanticSerp', 'GenerateContentQuery', 'SearchQuery'],
|
|
||||||
sliceIds: [
|
|
||||||
|
|
||||||
],
|
|
||||||
traceId: genRanHex(32),
|
|
||||||
scenario: 'Underside',
|
|
||||||
verbosity: 'verbose',
|
|
||||||
isStartOfSession: invocationId === 0,
|
|
||||||
message: {
|
|
||||||
locale: 'zh-CN',
|
|
||||||
market: 'zh-CN',
|
|
||||||
region: 'WW',
|
|
||||||
location: 'lat:47.639557;long:-122.128159;re=1000m;',
|
|
||||||
locationHints: [
|
|
||||||
{
|
|
||||||
country: 'Macedonia',
|
|
||||||
state: 'Centar',
|
|
||||||
city: 'Skopje',
|
|
||||||
zipcode: '1004',
|
|
||||||
timezoneoffset: 1,
|
|
||||||
countryConfidence: 8,
|
|
||||||
cityConfidence: 5,
|
|
||||||
Center: {
|
|
||||||
Latitude: 41.9961,
|
|
||||||
Longitude: 21.4317
|
|
||||||
},
|
|
||||||
RegionType: 2,
|
|
||||||
SourceType: 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
author: 'user',
|
|
||||||
inputMethod: 'Keyboard',
|
|
||||||
imageUrl: imageDate.blobId ? `https://www.bing.com/images/blob?bcid=${imageDate.blobId}` : undefined,
|
|
||||||
originalImageUrl: imageDate.processedBlobId ? `https://www.bing.com/images/blob?bcid=${imageDate.processedBlobId}` : undefined,
|
|
||||||
text: message,
|
|
||||||
messageType,
|
|
||||||
userIpAddress: await generateRandomIP(),
|
|
||||||
timestamp: currentDate
|
|
||||||
// messageType: 'SearchQuery'
|
|
||||||
},
|
|
||||||
tone: 'Creative',
|
|
||||||
conversationSignature,
|
|
||||||
participant: {
|
|
||||||
id: clientId
|
|
||||||
},
|
|
||||||
spokenTextMode: 'None',
|
|
||||||
conversationId,
|
|
||||||
previousMessages
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
invocationId: invocationId.toString(),
|
invocationId: invocationId.toString(),
|
||||||
target: 'chat',
|
target: 'chat',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue