mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 13:27:08 +00:00
fix: merge (maybe broken?)
This commit is contained in:
commit
df715e22a2
10 changed files with 120 additions and 47 deletions
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
|
||||
|
||||
> 由于相关领域发展快速,迭代较多,本文档有部分过时内容,不确定的问题可以开discussion或加群问群里的大佬们哦
|
||||
|
||||
### 推荐的相关文档和参考资料
|
||||
本README
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@ export class ChatGPTButtonHandler extends plugin {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 按钮处理器
|
||||
* @param e
|
||||
* @param options
|
||||
* @param reject
|
||||
* @deprecated
|
||||
* @return {Promise<{appid: number, rows: [{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]}]}|{appid: number, rows: [{buttons: [{render_data: {style: number, label: *, visited_label: *}, action: {data: *, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string},{render_data: {style: number, label: *, visited_label: *}, action: {data: *, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string},{render_data: {style: number, label: *, visited_label: *}, action: {data: *, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}]}]}|{appid: number, rows: [{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]},{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]},{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]},{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]}]}|{appid: number, rows: [{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]},{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]},{buttons: {render_data: {style: number, label, visited_label}, action: {data, permission: {type: number}, unsupport_tips: string, enter: boolean, type: number}, id: string}[]}]}|null>}
|
||||
*/
|
||||
async btnHandler (e, options, reject) {
|
||||
// logger.mark('[chatgpt按钮处理器]')
|
||||
if (!Config.enableMd) {
|
||||
|
|
|
|||
66
apps/chat.js
66
apps/chat.js
|
|
@ -74,43 +74,43 @@ export class chatgpt extends plugin {
|
|||
rule: [
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#chat3[sS]*',
|
||||
reg: '^#(图片)?chat3[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'chatgpt3'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#chat1[sS]*',
|
||||
reg: '^#(图片)?chat1[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'chatgpt1'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#chatglm[sS]*',
|
||||
reg: '^#(图片)?chatglm[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'chatglm'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#bing[sS]*',
|
||||
reg: '^#(图片)?bing[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'bing'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#claude(2|3|.ai)[sS]*',
|
||||
reg: '^#(图片)?claude(2|3|.ai)[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'claude2'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#claude[sS]*',
|
||||
reg: '^#(图片)?claude[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'claude'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#xh[sS]*',
|
||||
reg: '^#(图片)?xh[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'xh'
|
||||
},
|
||||
|
|
@ -124,25 +124,25 @@ export class chatgpt extends plugin {
|
|||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#glm4[sS]*',
|
||||
reg: '^#(图片)?glm4[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'glm4'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#qwen[sS]*',
|
||||
reg: '^#(图片)?qwen[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'qwen'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: '^#gemini[sS]*',
|
||||
reg: '^#(图片)?gemini[sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'gemini'
|
||||
},
|
||||
{
|
||||
/** 命令正则匹配 */
|
||||
reg: toggleMode === 'at' ? '^[^#][sS]*' : '^#chat[^gpt][sS]*',
|
||||
reg: toggleMode === 'at' ? '^[^#][sS]*' : '^#(图片)?chat[^gpt][sS]*',
|
||||
/** 执行方法 */
|
||||
fnc: 'chatgpt',
|
||||
log: false
|
||||
|
|
@ -483,6 +483,7 @@ export class chatgpt extends plugin {
|
|||
async chatgpt (e) {
|
||||
let msg = e.msg
|
||||
let prompt
|
||||
let forcePictureMode = false
|
||||
if (this.toggleMode === 'at') {
|
||||
if (!msg || e.msg?.startsWith('#')) {
|
||||
return false
|
||||
|
|
@ -533,7 +534,10 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
return false
|
||||
}
|
||||
prompt = _.replace(e.msg.trimStart(), '#chat', '').trim()
|
||||
if (e.msg.trimStart().startsWith('#图片chat')) {
|
||||
forcePictureMode = true
|
||||
}
|
||||
prompt = _.replace(e.msg.trimStart(), /#(图片)?chat/, '').trim()
|
||||
if (prompt.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -548,10 +552,10 @@ export class chatgpt extends plugin {
|
|||
const use = (userData.mode === 'default' ? null : userData.mode) || await redis.get('CHATGPT:USE') || 'api'
|
||||
// 自动化插件本月已发送xx条消息更新太快,由于延迟和缓存问题导致不同客户端不一样,at文本和获取的card不一致。因此单独处理一下
|
||||
prompt = prompt.replace(/^|本月已发送\d+条消息/, '')
|
||||
await this.abstractChat(e, prompt, use)
|
||||
await this.abstractChat(e, prompt, use, forcePictureMode)
|
||||
}
|
||||
|
||||
async abstractChat (e, prompt, use) {
|
||||
async abstractChat (e, prompt, use, forcePictureMode = false) {
|
||||
// 关闭私聊通道后不回复
|
||||
if (!e.isMaster && e.isPrivate && !Config.enablePrivateChat) {
|
||||
return false
|
||||
|
|
@ -819,6 +823,17 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
}
|
||||
let response = chatMessage?.text?.replace('\n\n\n', '\n')
|
||||
|
||||
if (handler.has('chatgpt.response.post')) {
|
||||
logger.debug('调用后处理器: chatgpt.response.post')
|
||||
handler.call('chatgpt.response.post', this.e, {
|
||||
content: response,
|
||||
use,
|
||||
prompt
|
||||
}, true).catch(err => {
|
||||
logger.error('后处理器出错', err)
|
||||
})
|
||||
}
|
||||
let mood = 'blandness'
|
||||
if (!response) {
|
||||
await this.reply('没有任何回复', true)
|
||||
|
|
@ -981,7 +996,7 @@ export class chatgpt extends plugin {
|
|||
} else {
|
||||
await this.reply('合成语音发生错误~')
|
||||
}
|
||||
} else if (userSetting.usePicture || (!Config.enableMd && Config.autoUsePicture && response.length > Config.autoUsePictureThreshold)) {
|
||||
} else if (forcePictureMode || userSetting.usePicture || (Config.autoUsePicture && response.length > Config.autoUsePictureThreshold)) {
|
||||
try {
|
||||
await this.renderImage(e, use, response, prompt, quotemessage, mood, chatMessage.suggestedResponses, imgUrls)
|
||||
} catch (err) {
|
||||
|
|
@ -1052,11 +1067,11 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
|
||||
async chatgpt1 (e) {
|
||||
return await this.otherMode(e, 'api', '#chat1')
|
||||
return await this.otherMode(e, 'api', /#(图片)?chat1/)
|
||||
}
|
||||
|
||||
async chatgpt3 (e) {
|
||||
return await this.otherMode(e, 'api3', '#chat3')
|
||||
return await this.otherMode(e, 'api3', /#(图片)?chat3/)
|
||||
}
|
||||
|
||||
async chatglm (e) {
|
||||
|
|
@ -1064,31 +1079,31 @@ export class chatgpt extends plugin {
|
|||
}
|
||||
|
||||
async bing (e) {
|
||||
return await this.otherMode(e, 'bing')
|
||||
return await this.otherMode(e, 'bing', /#(图片)?bing/)
|
||||
}
|
||||
|
||||
async claude2 (e) {
|
||||
return await this.otherMode(e, 'claude2', /^#claude(2|3|.ai)/)
|
||||
return await this.otherMode(e, 'claude2', /^#(图片)?claude(2|3|.ai)/)
|
||||
}
|
||||
|
||||
async claude (e) {
|
||||
return await this.otherMode(e, 'claude')
|
||||
return await this.otherMode(e, 'claude', /#(图片)?claude/)
|
||||
}
|
||||
|
||||
async qwen (e) {
|
||||
return await this.otherMode(e, 'qwen')
|
||||
return await this.otherMode(e, 'qwen', /#(图片)?qwen/)
|
||||
}
|
||||
|
||||
async glm4 (e) {
|
||||
return await this.otherMode(e, 'chatglm4', '#glm4')
|
||||
return await this.otherMode(e, 'chatglm4', /#(图片)?glm4/)
|
||||
}
|
||||
|
||||
async gemini (e) {
|
||||
return await this.otherMode(e, 'gemini')
|
||||
return await this.otherMode(e, 'gemini', /#(图片)?gemini/)
|
||||
}
|
||||
|
||||
async xh (e) {
|
||||
return await this.otherMode(e, 'xh')
|
||||
return await this.otherMode(e, 'xh', /#(图片)?xh/)
|
||||
}
|
||||
|
||||
async cacheContent (e, use, content, prompt, quote = [], mood = '', suggest = '', imgUrls = []) {
|
||||
|
|
@ -1396,7 +1411,8 @@ export class chatgpt extends plugin {
|
|||
if (prompt.length === 0) {
|
||||
return false
|
||||
}
|
||||
await this.abstractChat(e, prompt, mode)
|
||||
let forcePictureMode = e.msg.trimStart().startsWith('#图片')
|
||||
await this.abstractChat(e, prompt, mode, forcePictureMode)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
46
apps/example_handler.js
Normal file
46
apps/example_handler.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* 示例后处理器。你可以在example下面写一个新的。默认会调用所有此key的处理器
|
||||
*/
|
||||
export class ChatGPTResponsePostHandler extends plugin {
|
||||
constructor () {
|
||||
super({
|
||||
name: 'chatgpt文本回复后处理器',
|
||||
priority: -100,
|
||||
namespace: 'chatgpt-plugin',
|
||||
handler: [{
|
||||
key: 'chatgpt.response.post', // key必须是chatgpt.response.post
|
||||
fn: 'postHandler'
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
async postHandler (e, options, reject) {
|
||||
const { content, use, prompt } = options
|
||||
// 你可以在这里处理返回的文本,比如使用自定义的语音api来合成语音
|
||||
|
||||
// 返回值会被忽略
|
||||
// 以下是一个简单的例子
|
||||
// const response = await fetch('https://api.fish.audio/v1/tts', {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// Authorization: 'Bearer + key',
|
||||
// 'Content-Type': 'application/json'
|
||||
// },
|
||||
// body: JSON.stringify({
|
||||
// text: content,
|
||||
// reference_id: '1aacaeb1b840436391b835fd5513f4c4',
|
||||
// format: 'mp3',
|
||||
// latency: 'normal'
|
||||
// })
|
||||
// })
|
||||
//
|
||||
// if (!response.ok) {
|
||||
// throw new Error(`无法从服务器获取音频数据:${response.statusText}`)
|
||||
// }
|
||||
//
|
||||
// const audio = await response.blob()
|
||||
// // to Buffer
|
||||
// const buffer = await audio.arrayBuffer()
|
||||
// e.reply(segment.record(Buffer.from(buffer)))
|
||||
}
|
||||
}
|
||||
|
|
@ -186,13 +186,14 @@ export class Update extends plugin {
|
|||
* @returns
|
||||
*/
|
||||
async makeForwardMsg (title, msg, end) {
|
||||
let nickname = (this.e.bot ?? Bot).nickname
|
||||
const _bot = this.e.bot ?? Bot
|
||||
let nickname = _bot.nickname
|
||||
if (this.e.isGroup) {
|
||||
let info = await (this.e.bot ?? Bot).getGroupMemberInfo(this.e.group_id, (this.e.bot ?? Bot).uin)
|
||||
let info = await _bot?.pickMember?.(this.e.group_id, _bot.uin) || await _bot?.getGroupMemberInfo?.(this.e.group_id, _bot.uin)
|
||||
nickname = info.card || info.nickname
|
||||
}
|
||||
let userInfo = {
|
||||
user_id: (this.e.bot ?? Bot).uin,
|
||||
user_id: _bot.uin,
|
||||
nickname
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -239,9 +239,11 @@ export class CustomGoogleGeminiClient extends GoogleGeminiClient {
|
|||
} else {
|
||||
// execute function
|
||||
try {
|
||||
let isAdmin = ['admin', 'owner'].includes(this.e.sender.role) || (this.e.group?.is_admin && this.e.isMaster)
|
||||
let isOwner = ['owner'].includes(this.e.sender.role) || (this.e.group?.is_owner && this.e.isMaster)
|
||||
let args = Object.assign(functionCall.args, {
|
||||
isAdmin: this.e.group?.is_admin,
|
||||
isOwner: this.e.group?.is_owner,
|
||||
isAdmin,
|
||||
isOwner,
|
||||
sender: this.e.sender,
|
||||
mode: 'gemini'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import OpenAI from 'openai';
|
||||
import OpenAI from 'openai'
|
||||
import { BaseClient } from './BaseClient.js'
|
||||
|
||||
export default class OpenAILikeClient extends BaseClient {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,12 +63,12 @@ export function supportGuoba () {
|
|||
bottomHelpMessage: '独立的后台管理面板(默认3321端口),与锅巴类似。工具箱会有额外占用,启动速度稍慢,酌情开启。修改后需重启生效!!!',
|
||||
component: 'Switch'
|
||||
},
|
||||
{
|
||||
field: 'enableMd',
|
||||
label: 'QQ开启markdown',
|
||||
bottomHelpMessage: 'qq的第三方md,非QQBot。需要适配器实现segment.markdown和segment.button方可使用,否则不建议开启,会造成各种错误。默认关闭',
|
||||
component: 'Switch'
|
||||
},
|
||||
// {
|
||||
// field: 'enableMd',
|
||||
// label: 'QQ开启markdown',
|
||||
// bottomHelpMessage: 'qq的第三方md,非QQBot。需要适配器实现segment.markdown和segment.button方可使用,否则不建议开启,会造成各种错误。默认关闭',
|
||||
// component: 'Switch'
|
||||
// },
|
||||
{
|
||||
field: 'translateSource',
|
||||
label: '翻译来源',
|
||||
|
|
|
|||
|
|
@ -873,13 +873,13 @@ class Core {
|
|||
// 如果配了proxy(或者不在国内),而且有反代,但是没开启强制反代,将baseurl删掉
|
||||
delete opts.apiBaseUrl
|
||||
}
|
||||
const client = new OpenAI({
|
||||
apiKey: Config.apiKey,
|
||||
baseURL: opts.apiBaseUrl,
|
||||
fetch: newFetch
|
||||
})
|
||||
// const client = new OpenAI({
|
||||
// apiKey: Config.apiKey,
|
||||
// baseURL: opts.apiBaseUrl,
|
||||
// fetch: newFetch
|
||||
// })
|
||||
|
||||
// this.chatGPTApi = new ChatGPTAPI(opts)
|
||||
this.chatGPTApi = new ChatGPTAPI(opts)
|
||||
let option = {
|
||||
timeoutMs: 600000,
|
||||
completionParams,
|
||||
|
|
@ -1065,7 +1065,7 @@ async function collectTools (e) {
|
|||
}
|
||||
let systemAddition = ''
|
||||
if (e.isGroup) {
|
||||
let botInfo = await e.bot.getGroupMemberInfo(e.group_id, getUin(e), true)
|
||||
let botInfo = await e.bot?.pickMember?.(e.group_id, getUin(e), true) || await e.bot?.getGroupMemberInfo?.(e.group_id, getUin(e), true)
|
||||
if (botInfo.role !== 'member') {
|
||||
// 管理员才给这些工具
|
||||
tools.push(...[new EditCardTool(), new JinyanTool(), new KickOutTool(), new HandleMessageMsgTool(), new SetTitleTool()])
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ export class QueryUserinfoTool extends AbstractTool {
|
|||
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)
|
||||
if (e.isGroup) {
|
||||
let user = await e.bot?.pickMember?.(e.group_id, qq || e.sender.user_id, true) || 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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue