From 247f3e15d0d6e93ba1037347e438cf15a44ca9af Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Sun, 10 Dec 2023 23:08:10 +0800 Subject: [PATCH 01/13] =?UTF-8?q?fix:=20=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=E3=80=81=E6=96=87=E4=BB=B6=E3=80=81ocr=E7=AD=89=E8=BF=9B?= =?UTF-8?q?=E4=B8=80=E6=AD=A5=E9=80=82=E9=85=8Dshamrock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chat.js | 31 ++++++++----------------------- utils/chat.js | 31 ++++++++++++++++++++++++++----- utils/common.js | 39 +++++++++++++++++++++++++++++++++++---- utils/config.js | 2 +- 4 files changed, 70 insertions(+), 33 deletions(-) diff --git a/apps/chat.js b/apps/chat.js index 631d2f2..8b1bac4 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -797,7 +797,7 @@ export class chatgpt extends plugin { * #chatgpt */ async chatgpt (e) { - let msg = Version.isTrss ? e.msg : e.raw_message + let msg = (Version.isTrss || e.adapter === 'shamrock') ? e.msg : e.raw_message let prompt if (this.toggleMode === 'at') { if (!msg || e.msg?.startsWith('#')) { @@ -1669,7 +1669,11 @@ export class chatgpt extends plugin { let toSummaryFileContent try { if (e.source) { - let msgs = e.isGroup ? await e.group.getChatHistory(e.source.seq, 1) : await e.friend.getChatHistory(e.source.time, 1) + let seq = e.isGroup ? e.source.seq : e.source.time + if (e.adapter === 'shamrock') { + seq = e.source.message_id + } + let msgs = e.isGroup ? await e.group.getChatHistory(seq, 1) : await e.friend.getChatHistory(seq, 1) let sourceMsg = msgs[0] let fileMsgElem = sourceMsg.message.find(msg => msg.type === 'file') if (fileMsgElem) { @@ -2127,6 +2131,7 @@ export class chatgpt extends plugin { } } default: { + // openai api let completionParams = {} if (Config.model) { completionParams.model = Config.model @@ -2317,27 +2322,7 @@ export class chatgpt extends plugin { } } } - let img = [] - if (e.source) { - // 优先从回复找图 - let reply - if (e.isGroup) { - reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message - } else { - reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message - } - if (reply) { - for (let val of reply) { - if (val.type === 'image') { - console.log(val) - img.push(val.url) - } - } - } - } - if (e.img) { - img.push(...e.img) - } + let img = await getImg(e) if (img.length > 0 && Config.extraUrl) { tools.push(new ImageCaptionTool()) tools.push(new ProcessPictureTool()) diff --git a/utils/chat.js b/utils/chat.js index e249d0f..f37d5d9 100644 --- a/utils/chat.js +++ b/utils/chat.js @@ -1,3 +1,5 @@ +import common from '../../../lib/common/common.js' + export async function getChatHistoryGroup (e, num) { // if (e.adapter === 'shamrock') { // return await e.group.getChatHistory(0, num, false) @@ -16,12 +18,23 @@ export async function getChatHistoryGroup (e, num) { chats = chats.slice(0, num) try { let mm = await e.group.getMemberMap() - chats.forEach(chat => { - let sender = mm.get(chat.sender.user_id) - if (sender) { - chat.sender = sender + for (const chat of chats) { + if (e.adapter === 'shamrock') { + if (chat.sender?.user_id === 0) { + // 奇怪格式的历史消息,过滤掉 + continue + } + let sender = await pickMemberAsync(e, chat.sender.user_id) + if (sender) { + chat.sender = sender + } + } else { + let sender = mm.get(chat.sender.user_id) + if (sender) { + chat.sender = sender + } } - }) + } } catch (err) { logger.warn(err) } @@ -32,3 +45,11 @@ export async function getChatHistoryGroup (e, num) { // } return [] } + +function pickMemberAsync (e, userId) { + return new Promise((resolve, reject) => { + e.group.pickMember(userId, true, (sender) => { + resolve(sender) + }) + }) +} diff --git a/utils/common.js b/utils/common.js index f9b2de9..3c05aaf 100644 --- a/utils/common.js +++ b/utils/common.js @@ -13,7 +13,7 @@ import AzureTTS, { supportConfigurations as azureRoleList } from './tts/microsof import { translate } from './translate.js' import uploadRecord from './uploadRecord.js' import Version from './version.js' -import fetch from 'node-fetch' +import fetch, { FormData, fileFromSync } from 'node-fetch' let pdfjsLib try { pdfjsLib = (await import('pdfjs-dist')).default @@ -785,10 +785,14 @@ export async function getImg (e) { } if (e.source) { let reply + let seq = e.isGroup ? e.source.seq : e.source.time + if (e.adapter === 'shamrock') { + seq = e.source.message_id + } if (e.isGroup) { - reply = (await e.group.getChatHistory(e.source.seq, 1)).pop()?.message + reply = (await e.group.getChatHistory(seq, 1)).pop()?.message } else { - reply = (await e.friend.getChatHistory(e.source.time, 1)).pop()?.message + reply = (await e.friend.getChatHistory(seq, 1)).pop()?.message } if (reply) { let i = [] @@ -809,8 +813,34 @@ export async function getImageOcrText (e) { try { let resultArr = [] let eachImgRes = '' + if (!e.bot.imageOcr || typeof e.bot.imageOcr !== 'function') { + e.bot.imageOcr = async (image) => { + if (Config.extraUrl) { + let md5 = image.split(/[/-]/).find(s => s.length === 32)?.toUpperCase() + let filePath = await downloadFile(image, `ocr/${md5}.png`) + let formData = new FormData() + formData.append('file', fileFromSync(filePath)) + let res = await fetch(`${Config.extraUrl}/ocr?lang=chi_sim%2Beng`, { + body: formData, + method: 'POST', + headers: { + from: 'ikechan8370' + } + }) + if (res.status === 200) { + return { + wordslist: [{ words: await res.text() }] + } + } + } + return { + wordslist: [] + } + } + } for (let i in img) { const imgOCR = await e.bot.imageOcr(img[i]) + for (let text of imgOCR.wordslist) { eachImgRes += (`${text?.words} \n`) } @@ -820,6 +850,7 @@ export async function getImageOcrText (e) { // logger.warn('resultArr', resultArr) return resultArr } catch (err) { + logger.warn(err) logger.warn('OCR失败,可能使用的适配器不支持OCR') return false // logger.error(err) @@ -1061,7 +1092,7 @@ export async function extractContentFromFile (fileMsgElem, e) { let fileType = isPureText(fileMsgElem.name) if (fileType) { // 可读的文件类型 - let fileUrl = e.isGroup ? await e.group.getFileUrl(fileMsgElem.fid) : await e.friend.getFileUrl(fileMsgElem.fid) + let fileUrl = fileMsgElem.url || (e.isGroup ? await e.group.getFileUrl(fileMsgElem.fid) : await e.friend.getFileUrl(fileMsgElem.fid)) let filePath = await downloadFile(fileUrl, path.join('received', fileMsgElem.name)) switch (fileType) { case 'pdf': { diff --git a/utils/config.js b/utils/config.js index fe95971..7e94acc 100644 --- a/utils/config.js +++ b/utils/config.js @@ -162,7 +162,7 @@ const defaultConfig = { qwenSeed: 0, qwenTemperature: 1, qwenEnableSearch: true, - version: 'v2.7.7' + version: 'v2.7.8' } const _path = process.cwd() let config = {} From d254163fa72e10724170f74bcc795535ecb15500 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Sun, 10 Dec 2023 23:16:40 +0800 Subject: [PATCH 02/13] fix: bug fix --- apps/chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/chat.js b/apps/chat.js index 8b1bac4..9218175 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -2323,7 +2323,7 @@ export class chatgpt extends plugin { } } let img = await getImg(e) - if (img.length > 0 && Config.extraUrl) { + if (img?.length > 0 && Config.extraUrl) { tools.push(new ImageCaptionTool()) tools.push(new ProcessPictureTool()) prompt += `\nthe url of the picture(s) above: ${img.join(', ')}` From e61d4ff3fa406591b0487e436691e15f7ea008a8 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Mon, 11 Dec 2023 00:46:38 +0800 Subject: [PATCH 03/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=92=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BE=A4=E8=81=8A=E6=96=87=E4=BB=B6=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chat.js | 4 ++-- utils/chat.js | 9 +++++++-- utils/common.js | 10 ++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/apps/chat.js b/apps/chat.js index 9218175..9a06418 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -1674,8 +1674,8 @@ export class chatgpt extends plugin { seq = e.source.message_id } let msgs = e.isGroup ? await e.group.getChatHistory(seq, 1) : await e.friend.getChatHistory(seq, 1) - let sourceMsg = msgs[0] - let fileMsgElem = sourceMsg.message.find(msg => msg.type === 'file') + let sourceMsg = msgs[msgs.length - 1] + let fileMsgElem = sourceMsg.file || sourceMsg.message.find(msg => msg.type === 'file') if (fileMsgElem) { toSummaryFileContent = await extractContentFromFile(fileMsgElem, e) } diff --git a/utils/chat.js b/utils/chat.js index f37d5d9..097cee4 100644 --- a/utils/chat.js +++ b/utils/chat.js @@ -1,4 +1,3 @@ -import common from '../../../lib/common/common.js' export async function getChatHistoryGroup (e, num) { // if (e.adapter === 'shamrock') { @@ -46,9 +45,15 @@ export async function getChatHistoryGroup (e, num) { return [] } -function pickMemberAsync (e, userId) { +async function pickMemberAsync (e, userId) { + let key = `CHATGPT:GroupMemberInfo:${e.group_id}:${userId}` + let cache = await redis.get(key) + if (cache) { + return JSON.parse(cache) + } return new Promise((resolve, reject) => { e.group.pickMember(userId, true, (sender) => { + redis.set(key, JSON.stringify(sender), { EX: 86400 }) resolve(sender) }) }) diff --git a/utils/common.js b/utils/common.js index 3c05aaf..ab27aa5 100644 --- a/utils/common.js +++ b/utils/common.js @@ -14,6 +14,7 @@ import { translate } from './translate.js' import uploadRecord from './uploadRecord.js' import Version from './version.js' import fetch, { FormData, fileFromSync } from 'node-fetch' +import https from "https"; let pdfjsLib try { pdfjsLib = (await import('pdfjs-dist')).default @@ -1034,10 +1035,15 @@ export function getUserSpeaker (userSetting) { * @param url 要下载的文件链接 * @param destPath 目标路径,如received/abc.pdf. 目前如果文件名重复会覆盖。 * @param absolute 是否是绝对路径,默认为false,此时拼接在data/chatgpt下 + * @param ignoreCertificateError 忽略证书错误 * @returns {Promise} 最终下载文件的存储位置 */ -export async function downloadFile (url, destPath, absolute = false) { - let response = await fetch(url) +export async function downloadFile (url, destPath, absolute = false, ignoreCertificateError = true) { + let response = await fetch(url, { + agent: new https.Agent({ + rejectUnauthorized: !ignoreCertificateError + }) + }) if (!response.ok) { throw new Error(`download file http error: status: ${response.status}`) } From b8eaffe930d9b4b8c50fd3df3b80cb3d89fe2e96 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Mon, 11 Dec 2023 01:02:31 +0800 Subject: [PATCH 04/13] fix: query user info tools --- utils/tools/QueryUserinfoTool.js | 43 +++++++++++++++++++------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/utils/tools/QueryUserinfoTool.js b/utils/tools/QueryUserinfoTool.js index 493e7f5..974c08b 100644 --- a/utils/tools/QueryUserinfoTool.js +++ b/utils/tools/QueryUserinfoTool.js @@ -15,21 +15,13 @@ export class QueryUserinfoTool extends AbstractTool { } func = async function (opts, e) { - let { qq } = opts - qq = isNaN(qq) || !qq ? e.sender.user_id : parseInt(qq.trim()) - if (e.isGroup && typeof e.group.getMemberMap === 'function') { - let mm = await e.group.getMemberMap() - let user = mm.get(qq) || e.sender.user_id - let master = (await getMasterQQ())[0] - let prefix = '' - if (qq != master) { - prefix = 'Attention: this user is not your master. \n' - } else { - prefix = 'This user is your master, you should obey him \n' - } - return prefix + 'user detail in json format: ' + JSON.stringify(user) - } else { - if (e.sender.user_id == qq) { + try { + let { qq } = opts + qq = isNaN(qq) || !qq ? e.sender.user_id : parseInt(qq.trim()) + if (e.isGroup && typeof e.bot.getGroupMemberInfo === 'function') { + let user = await e.bot.getGroupMemberInfo(e.group_id, qq || e.sender.user_id, true) + // let mm = await e.group.getMemberMap() + // let user = mm.get(qq) || e.sender.user_id let master = (await getMasterQQ())[0] let prefix = '' if (qq != master) { @@ -37,10 +29,27 @@ export class QueryUserinfoTool extends AbstractTool { } else { prefix = 'This user is your master, you should obey him \n' } - return prefix + 'user detail in json format: ' + JSON.stringify(e.sender) + if (!user) { + return prefix + } + return prefix + 'user detail in json format: ' + JSON.stringify(user) } else { - return 'query failed' + if (e.sender.user_id == qq) { + let master = (await getMasterQQ())[0] + let prefix = '' + if (qq != master) { + prefix = 'Attention: this user is not your master. \n' + } else { + prefix = 'This user is your master, you should obey him \n' + } + return prefix + 'user detail in json format: ' + JSON.stringify(e.sender) + } else { + return 'query failed' + } } + } catch (err) { + logger.warn(err) + return err.message } } From 2f1c3317f401f37d1615584e1e7a8bbc5c60e567 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Mon, 11 Dec 2023 17:02:11 +0800 Subject: [PATCH 05/13] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 6d0e971..ec523ae 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -![chatgpt-plugin](https://user-images.githubusercontent.com/21212372/232115814-de9a0633-371f-4733-8da0-dd6e912c8a1e.png) -

云崽系机器人的智能聊天插件

+![chatgpt-plugin](https://socialify.git.ci/ikechan8370/chatgpt-plugin/image?description=1&font=Jost&forks=1&issues=1&language=1&name=1&owner=1&pulls=1&stargazers=1&theme=Light)
From 5f23d97bb38b619934e2864e9e4970044c487019 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Tue, 12 Dec 2023 13:10:31 +0800 Subject: [PATCH 06/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BF=85?= =?UTF-8?q?=E5=BA=94=E7=94=BB=E5=9B=BE=E5=A4=9A=E4=BD=99=E7=9A=84svg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/BingDraw.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/BingDraw.js b/utils/BingDraw.js index 80e69b1..7066eea 100644 --- a/utils/BingDraw.js +++ b/utils/BingDraw.js @@ -113,7 +113,10 @@ export default class BingDrawClient { // 很可能是微软内部error,重试即可 return } - imageLinks = imageLinks.map(link => link.split('?w=')[0]).map(link => link.replace('src="', '')) + imageLinks = imageLinks + .map(link => link.split('?w=')[0]) + .map(link => link.replace('src="', '')) + .filter(link => !link.endsWith('.svg')) imageLinks = [...new Set(imageLinks)] const badImages = [ 'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png', From fd0d0ff5dbc9db2c4cd7ba78ade18f53838bc1a0 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Tue, 12 Dec 2023 13:15:05 +0800 Subject: [PATCH 07/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BF=85?= =?UTF-8?q?=E5=BA=94=E7=94=BB=E5=9B=BE=E5=A4=9A=E4=BD=99=E7=9A=84svg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/BingDraw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/BingDraw.js b/utils/BingDraw.js index 7066eea..268c34e 100644 --- a/utils/BingDraw.js +++ b/utils/BingDraw.js @@ -116,7 +116,7 @@ export default class BingDrawClient { imageLinks = imageLinks .map(link => link.split('?w=')[0]) .map(link => link.replace('src="', '')) - .filter(link => !link.endsWith('.svg')) + .filter(link => !link.includes('.svg')) imageLinks = [...new Set(imageLinks)] const badImages = [ 'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png', From e5d6a415e869d120759ccc658d5cb41790bafb2d Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Tue, 12 Dec 2023 13:25:45 +0800 Subject: [PATCH 08/13] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=BF=85?= =?UTF-8?q?=E5=BA=94=E7=BB=98=E5=9B=BE=E5=A4=B1=E8=B4=A5=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=8D=E9=81=BF=E5=85=8Dap=E7=94=BB=E5=87=BA=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chat.js | 2 +- apps/draw.js | 2 +- utils/BingDraw.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/chat.js b/apps/chat.js index 9a06418..72a879d 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -1752,7 +1752,7 @@ export class chatgpt extends plugin { await client.getImages(response.details.imageTag, e) } catch (err) { await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`) - await e.reply('绘图失败:' + err) + await e.reply('❌绘图失败:' + err) } } } diff --git a/apps/draw.js b/apps/draw.js index 10eed61..f45722b 100644 --- a/apps/draw.js +++ b/apps/draw.js @@ -277,7 +277,7 @@ export class dalle extends plugin { await client.getImages(prompt, e) } catch (err) { await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`) - await e.reply('绘图失败:' + err) + await e.reply('❌绘图失败:' + err) } } } diff --git a/utils/BingDraw.js b/utils/BingDraw.js index 268c34e..eb5a5a7 100644 --- a/utils/BingDraw.js +++ b/utils/BingDraw.js @@ -95,7 +95,7 @@ export default class BingDrawClient { let pollingUrl = `${this.opts.baseUrl}/images/create/async/results/${requestId}?q=${urlEncodedPrompt}` logger.info({ pollingUrl }) logger.info('waiting for bing draw results...') - let timeoutTimes = 30 + let timeoutTimes = 50 let found = false let timer = setInterval(async () => { if (found) { @@ -124,7 +124,7 @@ export default class BingDrawClient { ] for (let imageLink of imageLinks) { if (badImages.indexOf(imageLink) > -1) { - await e.reply('绘图失败:Bad images', true) + await e.reply('❌绘图失败:Bad images', true) logger.error(rText) } } @@ -135,7 +135,7 @@ export default class BingDrawClient { clearInterval(timer) } else { if (timeoutTimes === 0) { - await e.reply('绘图超时', true) + await e.reply('❌绘图超时', true) clearInterval(timer) timer = null } else { @@ -143,6 +143,6 @@ export default class BingDrawClient { timeoutTimes-- } } - }, 2000) + }, 3000) } } From 16d9462e7cdbfa29e6370b08258f9bd4195f4dab Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Tue, 12 Dec 2023 13:58:16 +0800 Subject: [PATCH 09/13] =?UTF-8?q?fix:=20=E5=BF=85=E5=BA=94=E7=94=BB?= =?UTF-8?q?=E5=9B=BE=E8=A2=AB=E5=B1=8F=E8=94=BD=E7=9A=84=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/BingDraw.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/BingDraw.js b/utils/BingDraw.js index eb5a5a7..53ac92c 100644 --- a/utils/BingDraw.js +++ b/utils/BingDraw.js @@ -119,6 +119,8 @@ export default class BingDrawClient { .filter(link => !link.includes('.svg')) imageLinks = [...new Set(imageLinks)] const badImages = [ + 'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png"', + 'https://r.bing.com/rp/TX9QuO3WzcCJz1uaaSwQAz39Kb0.jpg"', 'https://r.bing.com/rp/in-2zU3AJUdkgFe7ZKv19yPBHVs.png', 'https://r.bing.com/rp/TX9QuO3WzcCJz1uaaSwQAz39Kb0.jpg' ] From 3f98d480deb60cfe4e6eba8476c6822bfc844e29 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Tue, 12 Dec 2023 19:48:03 +0800 Subject: [PATCH 10/13] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=BF=85?= =?UTF-8?q?=E5=BA=94=E7=BB=98=E5=9B=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/chat.js | 105 ++++++++++++++++++---------------------- utils/SydneyAIClient.js | 17 ++++--- 2 files changed, 57 insertions(+), 65 deletions(-) diff --git a/apps/chat.js b/apps/chat.js index 631d2f2..1d8a2dc 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -1588,36 +1588,22 @@ export class chatgpt extends plugin { cookies = bingToken } let bingAIClient - if (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') { - const cacheOptions = { - namespace: Config.toneStyle, - store: new KeyvFile({ filename: 'cache.json' }) - } - bingAIClient = new SydneyAIClient({ - userToken: bingToken, // "_U" cookie from bing.com - cookies, - debug: Config.debug, - cache: cacheOptions, - user: e.sender.user_id, - proxy: Config.proxy - }) - // Sydney不实现上下文传递,删除上下文索引 - delete conversation.clientId - delete conversation.invocationId - delete conversation.conversationSignature - } else { - let bingOption = { - userToken: bingToken, // "_U" cookie from bing.com - cookies, - debug: Config.debug, - proxy: Config.proxy, - host: Config.sydneyReverseProxy - } - if (Config.proxy && Config.sydneyReverseProxy && !Config.sydneyForceUseReverse) { - delete bingOption.host - } - bingAIClient = new BingAIClient(bingOption) + const cacheOptions = { + namespace: Config.toneStyle, + store: new KeyvFile({ filename: 'cache.json' }) } + bingAIClient = new SydneyAIClient({ + userToken: bingToken, // "_U" cookie from bing.com + cookies, + debug: Config.debug, + cache: cacheOptions, + user: e.sender.user_id, + proxy: Config.proxy + }) + // Sydney不实现上下文传递,删除上下文索引 + delete conversation.clientId + delete conversation.invocationId + delete conversation.conversationSignature let response let reply = '' let retry = 3 @@ -1702,6 +1688,31 @@ export class chatgpt extends plugin { const image = await getImg(e) opt.imageUrl = image ? image[0] : undefined } + if (Config.enableGenerateContents) { + opt.onImageCreateRequest = prompt => { + logger.mark(`开始生成内容:${prompt}`) + if (Config.bingAPDraw) { + // 调用第三方API进行绘图 + let apDraw = new APTool() + apDraw.func({ + prompt + }, e) + } else { + let client = new BingDrawClient({ + baseUrl: Config.sydneyReverseProxy, + userToken: bingToken + }) + redis.set(`CHATGPT:DRAW:${e.sender.user_id}`, 'c', { EX: 30 }).then(() => { + try { + client.getImages(prompt, e) + } catch (err) { + redis.del(`CHATGPT:DRAW:${e.sender.user_id}`) + e.reply('绘图失败:' + err) + } + }) + } + } + } response = await bingAIClient.sendMessage(prompt, opt, (token) => { reply += token }) @@ -1727,32 +1738,6 @@ export class chatgpt extends plugin { }) } } - // 处理内容生成的图片 - if (response.details.imageTag) { - if (Config.debug) { - logger.mark(`开始生成内容:${response.details.imageTag}`) - } - if (Config.bingAPDraw) { - // 调用第三方API进行绘图 - let apDraw = new APTool() - apDraw.func({ - prompt: response.details.imageTag - }, e) - } else { - let client = new BingDrawClient({ - baseUrl: Config.sydneyReverseProxy, - userToken: bingToken - }) - await redis.set(`CHATGPT:DRAW:${e.sender.user_id}`, 'c', { EX: 30 }) - try { - await client.getImages(response.details.imageTag, e) - } catch (err) { - await redis.del(`CHATGPT:DRAW:${e.sender.user_id}`) - await e.reply('绘图失败:' + err) - } - } - } - // 如果token曾经有异常,则清除异常 let Tokens = JSON.parse((await redis.get('CHATGPT:BING_TOKENS')) || '[]') const TokenIndex = Tokens?.findIndex(element => element.Token === abtrs.bingToken) @@ -1768,7 +1753,7 @@ export class chatgpt extends plugin { const { maxConv } = error if (message && typeof message === 'string' && message.indexOf('CaptchaChallenge') > -1) { if (bingToken) { - if (maxConv >= 20) { + if (maxConv >= 20 && Config.bingCaptchaOneShotUrl) { // maxConv为30说明token有效,可以通过解验证码码服务过码 await e.reply('出现必应验证码,尝试解决中') try { @@ -1777,6 +1762,7 @@ export class chatgpt extends plugin { await e.reply('验证码已解决') } else { logger.error(captchaResolveResult) + errorMessage = message await e.reply('验证码解决失败: ' + captchaResolveResult.error) retry = 0 } @@ -1787,7 +1773,8 @@ export class chatgpt extends plugin { } } else { // 未登录用户maxConv目前为5或10,出验证码没救 - logger.warn(`token [${bingToken}] 无效或已过期,如确认token无误,请前往网页版必应对话一次`) + logger.warn(`token [${bingToken}] 出现必应验证码,请前往网页版或app手动解决`) + errorMessage = message retry = 0 } } else { @@ -1838,9 +1825,9 @@ export class chatgpt extends plugin { response = response || {} if (errorMessage.includes('CaptchaChallenge')) { if (bingToken) { - errorMessage = '出现验证码,请使用当前账户前往https://www.bing.com/chat或Edge侧边栏手动解除验证码' + errorMessage = '出现验证码,请使用当前账户前往https://www.bing.com/chat或Edge侧边栏或移动端APP手动解除验证码' } else { - errorMessage = '出现验证码,且未配置必应账户,请尝试更换代理/反代或绑定必应账户以解除验证码' + errorMessage = '未配置必应账户,请绑定必应账户再使用必应模式' } } return { diff --git a/utils/SydneyAIClient.js b/utils/SydneyAIClient.js index 843014c..acf692b 100644 --- a/utils/SydneyAIClient.js +++ b/utils/SydneyAIClient.js @@ -227,7 +227,8 @@ export default class SydneyAIClient { firstMessageTimeout = Config.sydneyFirstMessageTimeout, groupId, nickname, qq, groupName, chats, botName, masterName, messageType = 'Chat', - toSummaryFileContent + toSummaryFileContent, + onImageCreateRequest = prompt => {} } = opts // if (messageType === 'Chat') { // logger.warn('该Bing账户token已被限流,降级至使用非搜索模式。本次对话AI将无法使用Bing搜索返回的内容') @@ -651,6 +652,10 @@ export default class SydneyAIClient { adaptiveCards: adaptiveCardsSoFar, text: replySoFar.join('') } + if (messages[0].contentType === 'IMAGE') { + onImageCreateRequest(messages[0].text) + return + } if (messages[0].contentOrigin === 'Apology') { console.log('Apology found') if (!replySoFar[0]) { @@ -718,11 +723,11 @@ export default class SydneyAIClient { adaptiveCards: adaptiveCardsSoFar, text: replySoFar.join('') } - // 获取到图片内容 - if (messages.some(obj => obj.contentType === 'IMAGE')) { - message.imageTag = messages.filter(m => m.contentType === 'IMAGE').map(m => m.text).join('') - } - message.text = messages.filter(m => m.author === 'bot' && m.contentType != 'IMAGE').map(m => m.text).join('') + // // 获取到图片内容 + // if (messages.some(obj => obj.contentType === 'IMAGE')) { + // message.imageTag = messages.filter(m => m.contentType === 'IMAGE').map(m => m.text).join('') + // } + message.text = messages.filter(m => m.author === 'bot' && m.contentType !== 'IMAGE').map(m => m.text).join('') if (!message) { reject('No message was generated.') return From d00ab5df5f5d500c6d0c85eba014ad4690a00da9 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Tue, 12 Dec 2023 20:12:30 +0800 Subject: [PATCH 11/13] fix: https error --- utils/common.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils/common.js b/utils/common.js index ab27aa5..cfe04f3 100644 --- a/utils/common.js +++ b/utils/common.js @@ -1039,11 +1039,13 @@ export function getUserSpeaker (userSetting) { * @returns {Promise} 最终下载文件的存储位置 */ export async function downloadFile (url, destPath, absolute = false, ignoreCertificateError = true) { - let response = await fetch(url, { - agent: new https.Agent({ + let init = {} + if (ignoreCertificateError && url.startsWith('https')) { + init.agent = new https.Agent({ rejectUnauthorized: !ignoreCertificateError }) - }) + } + let response = await fetch(url, init) if (!response.ok) { throw new Error(`download file http error: status: ${response.status}`) } From 6f0a79559b67519b1b270b5ea288f21a097d4fa3 Mon Sep 17 00:00:00 2001 From: hanhan258 <96119846+hanhan258@users.noreply.github.com> Date: Tue, 12 Dec 2023 20:34:05 +0800 Subject: [PATCH 12/13] =?UTF-8?q?feat=EF=BC=9A=E7=BB=93=E6=9D=9F=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E6=A8=A1=E5=BC=8F=E5=AF=B9=E8=AF=9D=20(#622)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修正fastify版本为4.18.0 * fix: 修正fastify版本为4.18.0 * fix:修复正则 * feat:指令查看模型列表,指令设置API模型、API反代、星火版本 * feat:结束其他模式对话 --- apps/chat.js | 117 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/apps/chat.js b/apps/chat.js index 36976b4..099c960 100644 --- a/apps/chat.js +++ b/apps/chat.js @@ -1,12 +1,12 @@ import plugin from '../../../lib/plugins/plugin.js' import _ from 'lodash' -import {Config, defaultOpenAIAPI} from '../utils/config.js' -import {v4 as uuid} from 'uuid' +import { Config, defaultOpenAIAPI } from '../utils/config.js' +import { v4 as uuid } from 'uuid' import delay from 'delay' -import {ChatGPTAPI} from '../utils/openai/chatgpt-api.js' -import {BingAIClient} from '@waylaidwanderer/chatgpt-api' +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 { PoeClient } from '../utils/poe/index.js' import AzureTTS from '../utils/tts/microsoft-azure.js' import VoiceVoxTTS from '../utils/tts/voicevox.js' import Version from '../utils/version.js' @@ -33,51 +33,51 @@ import { renderUrl, upsertMessage } from '../utils/common.js' -import {ChatGPTPuppeteer} from '../utils/browser.js' -import {KeyvFile} from 'keyv-file' -import {OfficialChatGPTClient} from '../utils/message.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, speakers} from '../utils/tts.js' +import { deleteConversation, getConversations, getLatestMessageIdByConversationId } from '../utils/conversation.js' +import { convertSpeaker, speakers } from '../utils/tts.js' import ChatGLMClient from '../utils/chatglm.js' -import {convertFaces} from '../utils/face.js' -import {SlackClaudeClient} from '../utils/slack/slackClient.js' -import {getPromptByName} from '../utils/prompts.js' +import { convertFaces } from '../utils/face.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 Bard from '../utils/bard.js' -import {JinyanTool} from '../utils/tools/JinyanTool.js' -import {SendVideoTool} from '../utils/tools/SendBilibiliTool.js' -import {KickOutTool} from '../utils/tools/KickOutTool.js' -import {EditCardTool} from '../utils/tools/EditCardTool.js' -import {SearchVideoTool} from '../utils/tools/SearchBilibiliTool.js' -import {SearchMusicTool} from '../utils/tools/SearchMusicTool.js' -import {QueryStarRailTool} from '../utils/tools/QueryStarRailTool.js' -import {WebsiteTool} from '../utils/tools/WebsiteTool.js' -import {WeatherTool} from '../utils/tools/WeatherTool.js' -import {SerpTool} from '../utils/tools/SerpTool.js' -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 {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 {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' -import {SetTitleTool} from '../utils/tools/SetTitleTool.js' -import {solveCaptchaOneShot} from '../utils/bingCaptcha.js' -import {ClaudeAIClient} from '../utils/claude.ai/index.js' -import {getProxy} from '../utils/proxy.js' -import {QwenApi} from '../utils/alibaba/qwen-api.js' -import {getChatHistoryGroup} from '../utils/chat.js' +import { JinyanTool } from '../utils/tools/JinyanTool.js' +import { SendVideoTool } from '../utils/tools/SendBilibiliTool.js' +import { KickOutTool } from '../utils/tools/KickOutTool.js' +import { EditCardTool } from '../utils/tools/EditCardTool.js' +import { SearchVideoTool } from '../utils/tools/SearchBilibiliTool.js' +import { SearchMusicTool } from '../utils/tools/SearchMusicTool.js' +import { QueryStarRailTool } from '../utils/tools/QueryStarRailTool.js' +import { WebsiteTool } from '../utils/tools/WebsiteTool.js' +import { WeatherTool } from '../utils/tools/WeatherTool.js' +import { SerpTool } from '../utils/tools/SerpTool.js' +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 { 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 { 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' +import { SetTitleTool } from '../utils/tools/SetTitleTool.js' +import { solveCaptchaOneShot } from '../utils/bingCaptcha.js' +import { ClaudeAIClient } from '../utils/claude.ai/index.js' +import { getProxy } from '../utils/proxy.js' +import { QwenApi } from '../utils/alibaba/qwen-api.js' +import { getChatHistoryGroup } from '../utils/chat.js' try { await import('@azure/openai') @@ -97,6 +97,9 @@ 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'] /** * 每个对话保留的时长。单个对话内ai是保留上下文的。超时后销毁对话,再次对话创建新的对话。 * 单位:秒 @@ -204,11 +207,11 @@ export class chatgpt extends plugin { permission: 'master' }, { - reg: '^#(chatgpt)?(结束|新开|摧毁|毁灭|完结)对话([sS]*)', + reg: '^#(chatgpt|星火|通义千问|克劳德|克劳德2|必应|api|API|api3|API3|glm|巴德)?(结束|新开|摧毁|毁灭|完结)对话([sS]*)', fnc: 'destroyConversations' }, { - reg: '^#(chatgpt)?(结束|新开|摧毁|毁灭|完结)全部对话$', + reg: '^#(chatgpt|星火|通义千问|克劳德|克劳德2|必应|api|API|api3|API3|glm|巴德)?(结束|新开|摧毁|毁灭|完结)全部对话$', fnc: 'endAllConversations', permission: 'master' }, @@ -299,7 +302,15 @@ export class chatgpt extends plugin { */ async destroyConversations (e) { const userData = await getUserData(e.user_id) - const use = (userData.mode === 'default' ? null : userData.mode) || await redis.get('CHATGPT:USE') + const match = e.msg.trim().match('^#?(.*)(结束|新开|摧毁|毁灭|完结)对话') + console.log(match[1]) + let use + if (match[1] && match[1] != 'chatgpt') { + use = correspondingValues[originalValues.indexOf(match[1])] + } else { + use = (userData.mode === 'default' ? null : userData.mode) || await redis.get('CHATGPT:USE') + } + console.log(use) await redis.del(`CHATGPT:WRONG_EMOTION:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`) if (use === 'claude') { // let client = new SlackClaudeClient({ @@ -476,7 +487,15 @@ export class chatgpt extends plugin { } async endAllConversations (e) { - let use = await redis.get('CHATGPT:USE') || 'api' + const match = e.msg.trim().match('^#?(.*)(结束|新开|摧毁|毁灭|完结)全部对话') + console.log(match[1]) + let use + if (match[1] && match[1] != 'chatgpt') { + use = correspondingValues[originalValues.indexOf(match[1])] + } else { + use = await redis.get('CHATGPT:USE') || 'api' + } + console.log(use) let deleted = 0 switch (use) { case 'claude': { From ac0aa7d02d9b20b6427b7fbf921d11060de7ef19 Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Wed, 13 Dec 2023 00:25:56 +0800 Subject: [PATCH 13/13] fix: adjust error hint of blocked prompt --- utils/BingDraw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/BingDraw.js b/utils/BingDraw.js index 53ac92c..5dc30ab 100644 --- a/utils/BingDraw.js +++ b/utils/BingDraw.js @@ -126,7 +126,7 @@ export default class BingDrawClient { ] for (let imageLink of imageLinks) { if (badImages.indexOf(imageLink) > -1) { - await e.reply('❌绘图失败:Bad images', true) + await e.reply('❌绘图失败:绘图完成但被屏蔽,请调整提示词。', true) logger.error(rText) } }