Merge branch 'ikechan8370:v2' into v2

This commit is contained in:
ifeif 2024-02-19 22:49:43 +08:00 committed by GitHub
commit d8454fe806
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 657 additions and 320 deletions

View file

@ -134,6 +134,7 @@ const newFetch = (url, options = {}) => {
export class chatgpt extends plugin {
constructor () {
let toggleMode = Config.toggleMode
let apiStream = Config.apiStream
super({
/** 功能名称 */
name: 'ChatGpt 对话',
@ -291,6 +292,7 @@ export class chatgpt extends plugin {
]
})
this.toggleMode = toggleMode
this.apiStream = apiStream
}
/**
@ -365,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)
@ -458,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
@ -1214,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) {
@ -1580,7 +1578,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因为可能之前有过期的被删了
@ -2265,7 +2263,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)
@ -2816,12 +2814,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

View file

@ -4,6 +4,7 @@ import { makeForwardMsg } from '../utils/common.js'
import _ from 'lodash'
import { Config } from '../utils/config.js'
import BingDrawClient from '../utils/BingDraw.js'
import fetch from 'node-fetch'
export class dalle extends plugin {
constructor (e) {
@ -32,11 +33,67 @@ export class dalle extends plugin {
{
reg: '^#bing(画图|绘图)',
fnc: 'bingDraw'
},
{
reg: '^#dalle3(画图|绘图)',
fnc: 'dalle3'
}
]
})
}
// dalle3
async dalle3 (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
return false
}
let ttl = await redis.ttl(`CHATGPT:DALLE3:${e.sender.user_id}`)
if (ttl > 0 && !e.isMaster) {
this.reply(`冷却中,请${ttl}秒后再试`)
return false
}
let prompt = e.msg.replace(/^#?dalle3(画图|绘图)/, '').trim()
console.log('draw方法被调用消息内容', prompt)
await redis.set(`CHATGPT:DALLE3:${e.sender.user_id}`, 'c', { EX: 30 })
await this.reply('正在为您绘制大小为1024x1024的1张图片预计消耗0.24美元余额,请稍候……')
try {
const response = await fetch(`${Config.openAiBaseUrl}/images/generations`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Config.apiKey}`
},
body: JSON.stringify({
model: 'dall-e-3',
prompt,
n: 1,
size: '1024x1024',
response_format: 'b64_json'
})
})
// 如果需要,可以解析响应体
const dataJson = await response.json()
console.log(dataJson)
if (dataJson.error) {
e.reply(`画图失败:${dataJson.error?.code}${dataJson.error?.message}`)
await redis.del(`CHATGPT:DALLE3:${e.sender.user_id}`)
return
}
if (dataJson.data[0].b64_json) {
e.reply(`描述:${dataJson.data[0].revised_prompt}`)
e.reply(segment.image(`base64://${dataJson.data[0].b64_json}`))
} else if (dataJson.data[0].url) {
e.reply(`哈哈哈,图来了~\n防止图💥,附上链接:\n${dataJson.data[0].url}`)
e.reply(segment.image(dataJson.data[0].url))
}
} catch (err) {
logger.error(err)
this.reply(`画图失败: ${err}`, true)
await redis.del(`CHATGPT:DALLE3:${e.sender.user_id}`)
}
}
async draw (e) {
if (!Config.enableDraw) {
this.reply('画图功能未开启')
@ -215,7 +272,7 @@ export class dalle extends plugin {
}
try {
let images = (await editImage(imgUrl, position.split(',').map(p => parseInt(p, 10)), prompt, num, size))
.map(image => segment.image(`base64://${image}`))
.map(image => segment.image(`base64://${image}`))
if (images.length > 1) {
this.reply(await makeForwardMsg(e, images, prompt))
} else {

View file

@ -148,7 +148,7 @@ let helpData = [
},
{
icon: 'confirm',
title: '#chatgpt必应切换(精准|均衡|创意|悉尼|自设定)',
title: '#chatgpt必应切换(精准|创意)',
desc: '切换Bing风格。'
},
{
@ -337,6 +337,6 @@ export class help extends plugin {
}
async help (e) {
await render(e, 'chatgpt-plugin', 'help/index', { helpData, version })
await render(e, 'chatgpt-plugin', 'help/index', { helpData, version })
}
}

View file

@ -49,42 +49,38 @@ export class history extends plugin {
return true
}
case 'bing': {
if (Config.toneStyle === 'Sydney' || Config.toneStyle === 'Custom') {
const cacheOptions = {
namespace: Config.toneStyle,
store: new KeyvFile({ filename: 'cache.json' })
}
let Keyv = await getKeyv()
let conversationsCache = new Keyv(cacheOptions)
const conversation = (await conversationsCache.get(`SydneyUser_${queryUser}`)) || {
messages: [],
createdAt: Date.now()
}
let key = `CHATGPT:CONVERSATIONS_BING:${queryUser}`
let previousConversation = await redis.get(key) || JSON.stringify({})
previousConversation = JSON.parse(previousConversation)
let parentMessageId = previousConversation.parentMessageId
let tmp = {}
const previousCachedMessages = getMessagesForConversation(conversation.messages, parentMessageId)
.map((message) => {
return {
text: message.message,
author: message.role === 'User' ? 'user' : 'bot'
}
})
previousCachedMessages.forEach(m => {
if (m.author === 'user') {
tmp.prompt = m.text
} else {
tmp.response = m.text
chat.push(tmp)
tmp = {}
const cacheOptions = {
namespace: Config.toneStyle,
store: new KeyvFile({ filename: 'cache.json' })
}
let Keyv = await getKeyv()
let conversationsCache = new Keyv(cacheOptions)
const conversation = (await conversationsCache.get(`SydneyUser_${queryUser}`)) || {
messages: [],
createdAt: Date.now()
}
let key = `CHATGPT:CONVERSATIONS_BING:${queryUser}`
let previousConversation = await redis.get(key) || JSON.stringify({})
previousConversation = JSON.parse(previousConversation)
let parentMessageId = previousConversation.parentMessageId
let tmp = {}
const previousCachedMessages = getMessagesForConversation(conversation.messages, parentMessageId)
.map((message) => {
return {
text: message.message,
author: message.role === 'User' ? 'user' : 'bot'
}
})
} else {
await e.reply('还不支持BING模式呢')
return true
}
previousCachedMessages.forEach(m => {
if (m.author === 'user') {
tmp.prompt = m.text
} else {
tmp.response = m.text
chat.push(tmp)
tmp = {}
}
})
break
}
}

View file

@ -341,6 +341,16 @@ export class ChatgptManagement extends plugin {
reg: '^#chatgpt必应(禁用|禁止|关闭|启用|开启)搜索$',
fnc: 'switchBingSearch',
permission: 'master'
},
{
reg: '^#chatgpt查看当前配置$',
fnc: 'queryConfig',
permission: 'master'
},
{
reg: '^#chatgpt(开启|关闭)(api|API)流$',
fnc: 'switchStream',
permission: 'master'
}
]
})
@ -1053,21 +1063,21 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
return
}
let map = {
精准: 'Sydney',
创意: 'Sydney',
均衡: 'Sydney',
Sydney: 'Sydney',
sydney: 'Sydney',
悉尼: 'Sydney',
默认: 'Sydney',
自设定: 'Custom',
自定义: 'Custom'
精准: 'Precise',
创意: 'Creative',
均衡: 'Precise',
Sydney: 'Creative',
sydney: 'Creative',
悉尼: 'Creative',
默认: 'Creative',
自设定: 'Creative',
自定义: 'Creative'
}
if (map[tongStyle]) {
Config.toneStyle = map[tongStyle]
await e.reply('切换成功')
} else {
await e.reply('没有这种风格。支持的风格:默认/创意/悉尼、自设定')
await e.reply('没有这种风格。支持的风格:`精准`和`创意`,均支持设定')
}
}
@ -1695,26 +1705,20 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
async setXinghuoModel (e) {
this.setContext('saveXinghuoModel')
await this.reply('1星火V1.5\n2星火V2\n3星火V3\n4星火助手')
await this.reply('1星火V1.5\n2星火V2\n3星火V3\n4星火V3.5\n5星火助手')
await this.reply('请发送序号', true)
return false
}
async switchBingSearch (e) {
if (e.msg.includes('启用') || e.msg.includes('开启')) {
Config.sydneyEnableSearch = true
await e.reply('已开启必应搜索')
} else {
Config.sydneyEnableSearch = false
await e.reply('已禁用必应搜索')
}
}
async saveXinghuoModel (e) {
if (!this.e.msg) return
let token = this.e.msg
let ver
switch (token) {
case '4':
ver = 'V3.5'
Config.xhmode = 'apiv3.5'
break
case '3':
ver = 'V3'
Config.xhmode = 'apiv3'
@ -1727,7 +1731,7 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
ver = 'V1.5'
Config.xhmode = 'api'
break
case '4':
case '5':
ver = '助手'
Config.xhmode = 'assistants'
break
@ -1737,4 +1741,46 @@ azure语音Azure 语音是微软 Azure 平台提供的一项语音服务,
await this.reply(`已成功切换到星火${ver}`, true)
this.finish('saveXinghuoModel')
}
async switchBingSearch (e) {
if (e.msg.includes('启用') || e.msg.includes('开启')) {
Config.sydneyEnableSearch = true
await e.reply('已开启必应搜索')
} else {
Config.sydneyEnableSearch = false
await e.reply('已禁用必应搜索')
}
}
async queryConfig (e) {
let use = await redis.get('CHATGPT:USE')
let config = []
config.push(`当前模式:${use}`)
config.push(`\n当前API模型${Config.model}`)
if (e.isPrivate) {
config.push(`\n当前APIKey${Config.apiKey}`)
config.push(`\n当前API反代${Config.openAiBaseUrl}`)
config.push(`\n当前必应反代:${Config.sydneyReverseProxy}`)
}
config.push(`\n当前星火模型:${Config.xhmode}`)
e.reply(config)
}
async switchStream (e) {
if (e.msg.includes('开启')) {
if (Config.apiStream) {
await e.reply('已经开启了')
return
}
Config.apiStream = true
await e.reply('好的已经打开API流式输出')
} else {
if (!Config.apiStream) {
await e.reply('已经是关闭得了')
return
}
Config.apiStream = false
await e.reply('好的已经关闭API流式输出')
}
}
}

View file

@ -149,14 +149,9 @@ export class help extends plugin {
}
}
let use = await redis.get('CHATGPT:USE') || 'api'
if (use.toLowerCase() === 'bing') {
if (Config.toneStyle === 'Custom') {
use = 'Custom'
}
}
const keyMap = {
api: 'promptPrefixOverride',
Custom: 'sydney',
bing: 'sydney',
claude: 'slackClaudeGlobalPreset',
qwen: 'promptPrefixOverride',
gemini: 'geminiPrompt',
@ -176,7 +171,7 @@ export class help extends plugin {
await redis.set(`CHATGPT:PROMPT_USE_${use}`, promptName)
await e.reply(`你当前正在使用${use}模式,已将该模式设定应用为"${promptName}"。更该设定后建议结束对话以使设定更好生效`, true)
} else {
await e.reply(`你当前正在使用${use}模式该模式不支持设定。支持设定的模式有API、自定义、Claude、通义千问和Gemini`, true)
await e.reply(`你当前正在使用${use}模式该模式不支持设定。支持设定的模式有API、必应、Claude、通义千问、星火和Gemini`, true)
}
}
@ -277,11 +272,6 @@ export class help extends plugin {
// return
}
let use = await redis.get('CHATGPT:USE') || 'api'
if (use.toLowerCase() === 'bing') {
if (Config.toneStyle === 'Custom') {
use = 'Custom'
}
}
let currentUse = e.msg.replace(/^#(chatgpt|ChatGPT)(上传|分享|共享)设定/, '')
if (!currentUse) {
currentUse = await redis.get(`CHATGPT:PROMPT_USE_${use}`)
@ -361,7 +351,7 @@ export class help extends plugin {
title: currentUse,
prompt: content,
qq: master || (getUin(this.e) + ''), // 上传者设定为主人qq或机器人qq
use: extraData.use === 'Custom' ? 'Sydney' : 'ChatGPT',
use: extraData.use === 'bing' ? 'Bing' : 'ChatGPT',
r18,
description
}