Skip to content

Commit

Permalink
Merge branch 'v2' of github.com:ikechan8370/chatgpt-plugin into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ikechan8370 committed Feb 28, 2024
2 parents cf7da0d + bf75c00 commit 9c73c99
Show file tree
Hide file tree
Showing 34 changed files with 1,779 additions and 643 deletions.
104 changes: 67 additions & 37 deletions apps/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import { getChatHistoryGroup } from '../utils/chat.js'
import { CustomGoogleGeminiClient } from '../client/CustomGoogleGeminiClient.js'
import { resizeAndCropImage } from '../utils/dalle.js'
import fs from 'fs'
import { ChatGLM4Client } from '../client/ChatGLM4Client.js'

const roleMap = {
owner: 'group owner',
Expand All @@ -106,8 +107,8 @@ 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']
const originalValues = ['星火', '通义千问', '克劳德', '克劳德2', '必应', 'api', 'API', 'api3', 'API3', 'glm', '巴德', '双子星', '双子座', '智谱']
const correspondingValues = ['xh', 'qwen', 'claude', 'claude2', 'bing', 'api', 'api', 'api3', 'api3', 'chatglm', 'bard', 'gemini', 'gemini', 'chatglm4']
/**
* 每个对话保留的时长。单个对话内ai是保留上下文的。超时后销毁对话,再次对话创建新的对话。
* 单位:秒
Expand All @@ -133,6 +134,7 @@ const newFetch = (url, options = {}) => {
export class chatgpt extends plugin {
constructor () {
let toggleMode = Config.toggleMode
let apiStream = Config.apiStream
super({
/** 功能名称 */
name: 'ChatGpt 对话',
Expand Down Expand Up @@ -196,6 +198,12 @@ export class chatgpt extends plugin {
reg: '^#星火(搜索|查找)助手',
fnc: 'searchxhBot'
},
{
/** 命令正则匹配 */
reg: '^#glm4[sS]*',
/** 执行方法 */
fnc: 'glm4'
},
{
/** 命令正则匹配 */
reg: '^#qwen[sS]*',
Expand All @@ -221,11 +229,11 @@ export class chatgpt extends plugin {
permission: 'master'
},
{
reg: '^#(chatgpt|星火|通义千问|克劳德|克劳德2|必应|api|API|api3|API3|glm|巴德)?(结束|新开|摧毁|毁灭|完结)对话([sS]*)',
reg: `^#?(${originalValues.join('|')})?(结束|新开|摧毁|毁灭|完结)对话([sS]*)$`,
fnc: 'destroyConversations'
},
{
reg: '^#(chatgpt|星火|通义千问|克劳德|克劳德2|必应|api|API|api3|API3|glm|巴德)?(结束|新开|摧毁|毁灭|完结)全部对话$',
reg: `^#?(${originalValues.join('|')})?(结束|新开|摧毁|毁灭|完结)全部对话$`,
fnc: 'endAllConversations',
permission: 'master'
},
Expand Down Expand Up @@ -284,6 +292,7 @@ export class chatgpt extends plugin {
]
})
this.toggleMode = toggleMode
this.apiStream = apiStream
}

/**
Expand Down Expand Up @@ -358,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)
Expand Down Expand Up @@ -419,6 +428,14 @@ export class chatgpt extends plugin {
await redis.del(`CHATGPT:CONVERSATIONS_GEMINI:${e.sender.user_id}`)
await this.reply('已结束当前对话,请@我进行聊天以开启新的对话', true)
}
} else if (use === 'chatglm4') {
let c = await redis.get(`CHATGPT:CONVERSATIONS_CHATGLM4:${e.sender.user_id}`)
if (!c) {
await this.reply('当前没有开启对话', true)
} else {
await redis.del(`CHATGPT:CONVERSATIONS_CHATGLM4:${e.sender.user_id}`)
await this.reply('已结束当前对话,请@我进行聊天以开启新的对话', true)
}
} else if (use === 'bing') {
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${e.sender.user_id}`)
if (!c) {
Expand All @@ -443,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
Expand Down Expand Up @@ -496,6 +513,14 @@ export class chatgpt extends plugin {
await redis.del(`CHATGPT:CONVERSATIONS_GEMINI:${qq}`)
await this.reply(`已结束${atUser}的对话,TA仍可以@我进行聊天以开启新的对话`, true)
}
} else if (use === 'chatglm4') {
let c = await redis.get(`CHATGPT:CONVERSATIONS_CHATGLM4:${qq}`)
if (!c) {
await this.reply(`当前${atUser}没有开启对话`, true)
} else {
await redis.del(`CHATGPT:CONVERSATIONS_CHATGLM4:${qq}`)
await this.reply(`已结束${atUser}的对话,TA仍可以@我进行聊天以开启新的对话`, true)
}
} else if (use === 'bing') {
let c = await redis.get(`CHATGPT:CONVERSATIONS_BING:${qq}`)
if (!c) {
Expand Down Expand Up @@ -639,6 +664,18 @@ export class chatgpt extends plugin {
}
break
}
case 'chatglm4': {
let qcs = await redis.keys('CHATGPT:CONVERSATIONS_CHATGLM4:*')
for (let i = 0; i < qcs.length; i++) {
await redis.del(qcs[i])
// todo clean last message id
if (Config.debug) {
logger.info('delete chatglm4 conversation bind: ' + qcs[i])
}
deleted++
}
break
}
}
await this.reply(`结束了${deleted}个用户的对话。`, true)
}
Expand Down Expand Up @@ -972,24 +1009,8 @@ export class chatgpt extends plugin {
}
}
}

let userSetting = await getUserReplySetting(this.e)
let useTTS = !!userSetting.useTTS
let speaker
if (Config.ttsMode === 'vits-uma-genshin-honkai') {
speaker = convertSpeaker(userSetting.ttsRole || Config.defaultTTSRole)
} else if (Config.ttsMode === 'azure') {
speaker = userSetting.ttsRoleAzure || Config.azureTTSSpeaker
} else if (Config.ttsMode === 'voicevox') {
speaker = userSetting.ttsRoleVoiceVox || Config.voicevoxTTSSpeaker
}
// 每个回答可以指定
let trySplit = prompt.split('回答:')
if (trySplit.length > 1 && speakers.indexOf(convertSpeaker(trySplit[0])) > -1) {
useTTS = true
speaker = convertSpeaker(trySplit[0])
prompt = trySplit[1]
}
const isImg = await getImg(e)
if (Config.imgOcr && !!isImg) {
let imgOcrText = await getImageOcrText(e)
Expand Down Expand Up @@ -1138,6 +1159,10 @@ export class chatgpt extends plugin {
key = `CHATGPT:CONVERSATIONS_GEMINI:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`
break
}
case 'chatglm4': {
key = `CHATGPT:CONVERSATIONS_CHATGLM4:${(e.isGroup && Config.groupMerge) ? e.group_id.toString() : e.sender.user_id}`
break
}
}
let ctime = new Date()
previousConversation = (key ? await redis.get(key) : null) || JSON.stringify({
Expand Down Expand Up @@ -1177,6 +1202,7 @@ export class chatgpt extends plugin {
await e.reply([element.tag, segment.image(element.url)])
})
}
// chatglm4图片,调整至sendMessage中处理
if (use === 'api' && !chatMessage) {
// 字数超限直接返回
return false
Expand All @@ -1190,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) {
Expand Down Expand Up @@ -1457,7 +1479,11 @@ export class chatgpt extends plugin {
}

async qwen (e) {
return await this.otherMode(e, 'gemini')
return await this.otherMode(e, 'qwen')
}

async glm4 (e) {
return await this.otherMode(e, 'chatglm4')
}

async gemini (e) {
Expand Down Expand Up @@ -1563,7 +1589,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,因为可能之前有过期的被删了
Expand Down Expand Up @@ -1916,7 +1942,8 @@ export class chatgpt extends plugin {
let response = await client.sendMessage(prompt, {
e,
chatId: conversation?.conversationId,
image: image ? image[0] : undefined
image: image ? image[0] : undefined,
system: Config.xhPrompt
})
return response
} else if (use === 'azure') {
Expand Down Expand Up @@ -2159,6 +2186,15 @@ export class chatgpt extends plugin {
}
option.system = system
return await client.sendMessage(prompt, option)
} else if (use === 'chatglm4') {
const client = new ChatGLM4Client({
refreshToken: Config.chatglmRefreshToken
})
let resp = await client.sendMessage(prompt, conversation)
if (resp.image) {
e.reply(segment.image(resp.image), true)
}
return resp
} else {
// openai api
let completionParams = {}
Expand Down Expand Up @@ -2239,7 +2275,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)
Expand Down Expand Up @@ -2790,12 +2826,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
Expand Down
67 changes: 64 additions & 3 deletions apps/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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('画图功能未开启')
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -267,10 +324,14 @@ export class dalle extends plugin {
const index = bingTokens.findIndex(element => element.Token === bingToken)
bingTokens[index].Usage += 1
await redis.set('CHATGPT:BING_TOKENS', JSON.stringify(bingTokens))

let cookie
if (bingToken.includes('=')) {
cookie = bingToken
}
let client = new BingDrawClient({
baseUrl: Config.sydneyReverseProxy,
userToken: bingToken
userToken: bingToken,
cookies: cookie
})
await redis.set(`CHATGPT:DRAW:${e.sender.user_id}`, 'c', { EX: 30 })
try {
Expand Down
Loading

0 comments on commit 9c73c99

Please sign in to comment.