diff --git a/client/CustomGoogleGeminiClient.js b/client/CustomGoogleGeminiClient.js index 7953764c..9276a4e5 100644 --- a/client/CustomGoogleGeminiClient.js +++ b/client/CustomGoogleGeminiClient.js @@ -71,7 +71,7 @@ export class CustomGoogleGeminiClient extends GoogleGeminiClient { * @param {{conversationId: string?, parentMessageId: string?, stream: boolean?, onProgress: function?, functionResponse: FunctionResponse?, system: string?, image: string?}} opt * @returns {Promise<{conversationId: string?, parentMessageId: string, text: string, id: string}>} */ - async sendMessage (text, opt) { + async sendMessage (text, opt = {}) { let history = await this.getHistory(opt.parentMessageId) let systemMessage = opt.system if (systemMessage) { @@ -208,9 +208,10 @@ export class CustomGoogleGeminiClient extends GoogleGeminiClient { // execute function try { let args = Object.assign(functionCall.args, { - isAdmin: this.e.group.is_admin, - isOwner: this.e.group.is_owner, - sender: this.e.sender + isAdmin: this.e.group?.is_admin, + isOwner: this.e.group?.is_owner, + sender: this.e.sender, + mode: 'gemini' }) functionResponse.response.content = await chosenTool.func(args, this.e) if (this.debug) { diff --git a/guoba.support.js b/guoba.support.js index 23ee28ed..f408b085 100644 --- a/guoba.support.js +++ b/guoba.support.js @@ -403,6 +403,12 @@ export function supportGuoba () { bottomHelpMessage: '加强主人认知。希望机器人认清主人,避免NTR可开启。开启后可能会与自设定的内容有部分冲突。sydney模式可以放心开启', component: 'Switch' }, + { + field: 'sydneyGPT4Turbo', + label: '使用GPT4-turbo', + bottomHelpMessage: '目前仅Copilot Pro可开启。非pro用户开启会报错。', + component: 'Switch' + }, { field: 'enableGenerateContents', label: '允许生成图像等内容', diff --git a/utils/SydneyAIClient.js b/utils/SydneyAIClient.js index 16e98364..4165b7a8 100644 --- a/utils/SydneyAIClient.js +++ b/utils/SydneyAIClient.js @@ -383,6 +383,9 @@ export default class SydneyAIClient { if (!Config.sydneyEnableSearch || toSummaryFileContent?.content) { optionsSets.push(...['nosearchall']) } + if (Config.sydneyGPT4Turbo) { + optionsSets.push('gpt4tmnc') + } let maxConv = Config.maxNumUserMessagesInConversation const currentDate = moment().format('YYYY-MM-DDTHH:mm:ssZ') const imageDate = await this.kblobImage(opts.imageUrl) @@ -482,6 +485,7 @@ export default class SydneyAIClient { // } ] } + if (encryptedconversationsignature) { delete argument0.conversationSignature } diff --git a/utils/config.js b/utils/config.js index ff50aa02..4705aa56 100644 --- a/utils/config.js +++ b/utils/config.js @@ -39,6 +39,7 @@ const defaultConfig = { sydneyBrainWashStrength: 15, sydneyBrainWashName: 'Sydney', sydneyMood: false, + sydneyGPT4Turbo: false, sydneyImageRecognition: false, sydneyMoodTip: 'Your response should be divided into two parts, namely, the text and your mood. The mood available to you can only include: blandness, happy, shy, frustrated, disgusted, and frightened.All content should be replied in this format {"text": "", "mood": ""}.All content except mood should be placed in text, It is important to ensure that the content you reply to can be parsed by json.', enableSuggestedResponses: false, diff --git a/utils/tools/WebsiteTool.js b/utils/tools/WebsiteTool.js index b90ebe0d..e27e3871 100644 --- a/utils/tools/WebsiteTool.js +++ b/utils/tools/WebsiteTool.js @@ -5,6 +5,7 @@ import fetch from 'node-fetch' import proxy from 'https-proxy-agent' import { getMaxModelTokens } from '../common.js' import { ChatGPTPuppeteer } from '../browser.js' +import { CustomGoogleGeminiClient } from '../../client/CustomGoogleGeminiClient.js' export class WebsiteTool extends AbstractTool { name = 'website' @@ -19,7 +20,7 @@ export class WebsiteTool extends AbstractTool { } func = async function (opts) { - let { url } = opts + let { url, mode, e } = opts try { // let res = await fetch(url, { // headers: { @@ -58,34 +59,49 @@ export class WebsiteTool extends AbstractTool { .replace(/[\n\r]/gi, '') // 去除回车换行 .replace(/\s{2}/g, '') // 多个空格只保留一个空格 .replace('', '') // 去除声明 - let maxModelTokens = getMaxModelTokens(Config.model) - text = text.slice(0, Math.min(text.length, maxModelTokens - 1600)) - let completionParams = { - // model: Config.model - model: 'gpt-3.5-turbo-16k' + + if (mode === 'gemini') { + let client = new CustomGoogleGeminiClient({ + e, + userId: e?.sender?.user_id, + key: Config.geminiKey, + model: Config.geminiModel, + baseUrl: Config.geminiBaseUrl, + debug: Config.debug + }) + const htmlContentSummaryRes = await client.sendMessage(`去除与主体内容无关的部分,从中整理出主体内容并转换成md格式,不需要主观描述性的语言与冗余的空白行。${text}`) + let htmlContentSummary = htmlContentSummaryRes.text + return `this is the main content of website:\n ${htmlContentSummary}` + } else { + let maxModelTokens = getMaxModelTokens(Config.model) + text = text.slice(0, Math.min(text.length, maxModelTokens - 1600)) + let completionParams = { + // model: Config.model + model: 'gpt-3.5-turbo-16k' + } + let api = new ChatGPTAPI({ + apiBaseUrl: Config.openAiBaseUrl, + apiKey: Config.apiKey, + debug: false, + completionParams, + fetch: (url, options = {}) => { + const defaultOptions = Config.proxy + ? { + agent: proxy(Config.proxy) + } + : {} + const mergedOptions = { + ...defaultOptions, + ...options + } + return fetch(url, mergedOptions) + }, + maxModelTokens + }) + const htmlContentSummaryRes = await api.sendMessage(`去除与主体内容无关的部分,从中整理出主体内容并转换成md格式,不需要主观描述性的语言与冗余的空白行。${text}`, { completionParams }) + let htmlContentSummary = htmlContentSummaryRes.text + return `this is the main content of website:\n ${htmlContentSummary}` } - let api = new ChatGPTAPI({ - apiBaseUrl: Config.openAiBaseUrl, - apiKey: Config.apiKey, - debug: false, - completionParams, - fetch: (url, options = {}) => { - const defaultOptions = Config.proxy - ? { - agent: proxy(Config.proxy) - } - : {} - const mergedOptions = { - ...defaultOptions, - ...options - } - return fetch(url, mergedOptions) - }, - maxModelTokens - }) - const htmlContentSummaryRes = await api.sendMessage(`去除与主体内容无关的部分,从中整理出主体内容并转换成md格式,不需要主观描述性的语言与冗余的空白行。${text}`, { completionParams }) - let htmlContentSummary = htmlContentSummaryRes.text - return `this is the main content of website:\n ${htmlContentSummary}` } catch (err) { return `failed to visit the website, error: ${err.toString()}` }