mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 05:17:10 +00:00
fix: 调试设定和伪人
This commit is contained in:
parent
efb5a8f174
commit
3c77da5373
11 changed files with 293 additions and 34 deletions
28
apps/bym.js
28
apps/bym.js
|
|
@ -2,6 +2,7 @@ import ChatGPTConfig from '../config/config.js'
|
|||
import { Chaite } from 'chaite'
|
||||
import { intoUserMessage, toYunzai } from '../utils/message.js'
|
||||
import common from '../../../lib/common/common.js'
|
||||
import { getGroupContextPrompt } from '../utils/group.js'
|
||||
|
||||
export class bym extends plugin {
|
||||
constructor () {
|
||||
|
|
@ -9,11 +10,12 @@ export class bym extends plugin {
|
|||
name: 'ChatGPT-Plugin伪人模式',
|
||||
dsc: 'ChatGPT-Plugin伪人模式',
|
||||
event: 'message',
|
||||
priority: -150,
|
||||
priority: 6000,
|
||||
rule: [
|
||||
{
|
||||
reg: '^#chatgpt伪人模式$',
|
||||
fnc: 'bym'
|
||||
reg: '^[^#][sS]*',
|
||||
fnc: 'bym',
|
||||
log: false
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -23,11 +25,19 @@ export class bym extends plugin {
|
|||
if (!ChatGPTConfig.bym.enable) {
|
||||
return false
|
||||
}
|
||||
let prob = ChatGPTConfig.bym.probability
|
||||
if (ChatGPTConfig.bym.hit.find(keyword => e.msg?.includes(keyword))) {
|
||||
prob = 1
|
||||
}
|
||||
if (Math.random() > prob) {
|
||||
return false
|
||||
}
|
||||
logger.info('伪人模式触发')
|
||||
let recall = false
|
||||
let presetId = ChatGPTConfig.bym.defaultPreset
|
||||
if (ChatGPTConfig.bym.presetMap && ChatGPTConfig.bym.presetMap.length > 0) {
|
||||
const option = ChatGPTConfig.bym.presetMap.sort((a, b) => a.priority - b.priority)
|
||||
.find(item => item.keywords.find(keyword => e.msg.includes(keyword)))
|
||||
.find(item => item.keywords.find(keyword => e.msg?.includes(keyword)))
|
||||
if (option) {
|
||||
presetId = option.presetId
|
||||
}
|
||||
|
|
@ -49,6 +59,12 @@ export class bym extends plugin {
|
|||
}
|
||||
preset.sendMessageOption.systemOverride = ChatGPTConfig.bym.presetPrefix + preset.sendMessageOption.systemOverride
|
||||
}
|
||||
if (ChatGPTConfig.bym.temperature >= 0) {
|
||||
preset.sendMessageOption.temperature = ChatGPTConfig.bym.temperature
|
||||
}
|
||||
if (ChatGPTConfig.bym.maxTokens > 0) {
|
||||
preset.sendMessageOption.maxTokens = ChatGPTConfig.bym.maxTokens
|
||||
}
|
||||
const userMessage = await intoUserMessage(e, {
|
||||
handleReplyText: true,
|
||||
handleReplyImage: true,
|
||||
|
|
@ -71,6 +87,10 @@ export class bym extends plugin {
|
|||
this.reply(forwardElement)
|
||||
}
|
||||
}
|
||||
if (ChatGPTConfig.llm.enableGroupContext && e.isGroup) {
|
||||
const contextPrompt = await getGroupContextPrompt(e, ChatGPTConfig.llm.groupContextLength)
|
||||
preset.sendMessageOption.systemOverride = preset.sendMessageOption.systemOverride ? preset.sendMessageOption.systemOverride + '\n' + contextPrompt : contextPrompt
|
||||
}
|
||||
// 发送
|
||||
const response = await Chaite.getInstance().sendMessage(userMessage, e, {
|
||||
...preset.sendMessageOption,
|
||||
|
|
|
|||
38
apps/chat.js
38
apps/chat.js
|
|
@ -1,6 +1,8 @@
|
|||
import Config from '../config/config.js'
|
||||
import { Chaite, SendMessageOption } from 'chaite'
|
||||
import { getPreset, intoUserMessage, toYunzai } from '../utils/message.js'
|
||||
import { YunzaiUserState } from '../models/chaite/user_state_storage.js'
|
||||
import { getGroupContextPrompt, getGroupHistory } from '../utils/group.js'
|
||||
|
||||
export class Chat extends plugin {
|
||||
constructor () {
|
||||
|
|
@ -8,19 +10,34 @@ export class Chat extends plugin {
|
|||
name: 'ChatGPT-Plugin对话',
|
||||
dsc: 'ChatGPT-Plugin对话',
|
||||
event: 'message',
|
||||
priority: 0,
|
||||
priority: 500,
|
||||
rule: [
|
||||
{
|
||||
reg: '^[^#][sS]*',
|
||||
fnc: 'chat',
|
||||
log: false
|
||||
},
|
||||
{
|
||||
reg: '#hi',
|
||||
fnc: 'history'
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
async chat (e) {
|
||||
const state = await Chaite.getInstance().getUserStateStorage().getItem(e.sender.user_id + '')
|
||||
let state = await Chaite.getInstance().getUserStateStorage().getItem(e.sender.user_id + '')
|
||||
if (!state) {
|
||||
state = new YunzaiUserState(e.sender.user_id, e.sender.nickname, e.sender.card)
|
||||
await Chaite.getInstance().getUserStateStorage().setItem(e.sender.user_id + '', state)
|
||||
}
|
||||
const preset = await getPreset(e, state?.settings.preset || Config.llm.defaultChatPresetId, Config.basic.toggleMode, Config.basic.togglePrefix)
|
||||
if (!preset) {
|
||||
logger.debug('不满足对话触发条件或未找到预设,不进入对话')
|
||||
return false
|
||||
} else {
|
||||
logger.info('进入对话, prompt: ' + e.msg)
|
||||
}
|
||||
const sendMessageOptions = SendMessageOption.create(state?.settings)
|
||||
sendMessageOptions.onMessageWithToolCall = async content => {
|
||||
const { msgs, forward } = await toYunzai(e, [content])
|
||||
|
|
@ -31,11 +48,6 @@ export class Chat extends plugin {
|
|||
this.reply(forwardElement)
|
||||
}
|
||||
}
|
||||
const preset = await getPreset(e, state?.settings.preset || Config.llm.defaultChatPresetId, Config.basic.toggleMode, Config.basic.togglePrefix)
|
||||
if (!preset) {
|
||||
logger.debug('不满足对话触发条件或未找到预设,不进入对话')
|
||||
return false
|
||||
}
|
||||
const userMessage = await intoUserMessage(e, {
|
||||
handleReplyText: false,
|
||||
handleReplyImage: true,
|
||||
|
|
@ -45,10 +57,17 @@ export class Chat extends plugin {
|
|||
toggleMode: Config.basic.toggleMode,
|
||||
togglePrefix: Config.basic.togglePrefix
|
||||
})
|
||||
if (Config.llm.enableGroupContext && e.isGroup) {
|
||||
const contextPrompt = await getGroupContextPrompt(e, Config.llm.groupContextLength)
|
||||
sendMessageOptions.systemOverride = sendMessageOptions.systemOverride ? sendMessageOptions.systemOverride + '\n' + contextPrompt : (preset.sendMessageOption.systemOverride + contextPrompt)
|
||||
}
|
||||
const response = await Chaite.getInstance().sendMessage(userMessage, e, {
|
||||
...sendMessageOptions,
|
||||
chatPreset: preset
|
||||
})
|
||||
// 更新当前聊天进度
|
||||
state.current.messageId = response.id
|
||||
await Chaite.getInstance().getUserStateStorage().setItem(e.sender.user_id + '', state)
|
||||
const { msgs, forward } = await toYunzai(e, response.contents)
|
||||
if (msgs.length > 0) {
|
||||
await e.reply(msgs, true)
|
||||
|
|
@ -57,4 +76,9 @@ export class Chat extends plugin {
|
|||
this.reply(forwardElement)
|
||||
}
|
||||
}
|
||||
|
||||
async history (e) {
|
||||
const history = await getGroupHistory(e, 10)
|
||||
e.reply(JSON.stringify(history))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import ChatGPTConfig from '../config/config.js'
|
||||
import { createCRUDCommandRules, createSwitchCommandRules } from '../utils/command.js'
|
||||
import { Chaite } from 'chaite'
|
||||
import * as crypto from 'node:crypto'
|
||||
|
||||
export class ChatGPTManagement extends plugin {
|
||||
constructor () {
|
||||
|
|
@ -17,7 +18,7 @@ export class ChatGPTManagement extends plugin {
|
|||
permission: 'master'
|
||||
},
|
||||
{
|
||||
reg: `^${cmdPrefix}结束(全部)?对话$`,
|
||||
reg: `^(${cmdPrefix})?#?结束(全部)?对话$`,
|
||||
fnc: 'destroyConversation'
|
||||
},
|
||||
{
|
||||
|
|
@ -27,18 +28,22 @@ export class ChatGPTManagement extends plugin {
|
|||
}
|
||||
]
|
||||
})
|
||||
this.initCommand(cmdPrefix)
|
||||
if (!Chaite.getInstance()) {
|
||||
const waitForChaite = async () => {
|
||||
while (!Chaite.getInstance()) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
}
|
||||
return Chaite.getInstance()
|
||||
}
|
||||
waitForChaite().then(() => {
|
||||
this.initCommand(cmdPrefix)
|
||||
})
|
||||
} else {
|
||||
this.initCommand(cmdPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
async initCommand (cmdPrefix) {
|
||||
const waitForChaite = async () => {
|
||||
while (!Chaite.getInstance()) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
}
|
||||
return Chaite.getInstance()
|
||||
}
|
||||
|
||||
await waitForChaite()
|
||||
initCommand (cmdPrefix) {
|
||||
this.rule.push(...[
|
||||
...createCRUDCommandRules.bind(this)(cmdPrefix, '渠道', 'channels'),
|
||||
...createCRUDCommandRules.bind(this)(cmdPrefix, '预设', 'presets'),
|
||||
|
|
@ -94,7 +99,11 @@ export class ChatGPTManagement extends plugin {
|
|||
this.reply(`已结束${num}个用户的对话`)
|
||||
} else {
|
||||
const state = await Chaite.getInstance().getUserStateStorage().getItem(e.sender.user_id + '')
|
||||
state.current.conversationId = ''
|
||||
if (!state) {
|
||||
this.reply('当前未开启对话')
|
||||
return false
|
||||
}
|
||||
state.current.conversationId = crypto.randomUUID()
|
||||
state.current.messageId = ''
|
||||
await Chaite.getInstance().getUserStateStorage().setItem(e.sender.user_id + '', state)
|
||||
this.reply('已结束当前对话')
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class ChatGPTConfig {
|
|||
// 是否开启调试模式
|
||||
debug: false,
|
||||
// 一般命令的开头
|
||||
commandPrefix: '^#chatgpt'
|
||||
commandPrefix: '#chatgpt'
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,7 +80,12 @@ class ChatGPTConfig {
|
|||
* promptBlockWords: string[],
|
||||
* responseBlockWords: string[],
|
||||
* blockStrategy: 'full' | 'mask',
|
||||
* blockWordMask: string
|
||||
* blockWordMask: string,
|
||||
* enableGroupContext: boolean,
|
||||
* groupContextLength: number,
|
||||
* groupContextTemplatePrefix: string,
|
||||
* groupContextTemplateMessage: string,
|
||||
* groupContextTemplateSuffix: string
|
||||
* }}
|
||||
*/
|
||||
llm = {
|
||||
|
|
@ -105,7 +110,21 @@ class ChatGPTConfig {
|
|||
// 触发屏蔽词的策略,完全屏蔽或仅屏蔽关键词
|
||||
blockStrategy: 'full',
|
||||
// 如果blockStrategy为mask,屏蔽词的替换字符
|
||||
blockWordMask: '***'
|
||||
blockWordMask: '***',
|
||||
// 是否开启群组上下文
|
||||
enableGroupContext: false,
|
||||
// 群组上下文长度
|
||||
groupContextLength: 20,
|
||||
// 用于组装群聊上下文提示词的模板前缀
|
||||
groupContextTemplatePrefix: 'Latest several messages in the group chat:\n' +
|
||||
'| sender.card | sender.nickname | sender.user_id | sender.role | sender.title | time | messageId | raw_message |\n' +
|
||||
'|---|---|---|---|---|---|---|---|',
|
||||
// 用于组装群聊上下文提示词的模板内容部分,每一条消息作为message,仿照示例填写
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
groupContextTemplateMessage: '| ${message.sender.card} | ${message.sender.nickname} | ${message.sender.user_id} | ${message.sender.role} | ${message.sender.title} | ${message.time} | ${message.messageId} | ${message.raw_message} |',
|
||||
// 用于组装群聊上下文提示词的模板后缀
|
||||
groupContextTemplateSuffix: '\n'
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ export class LowDBHistoryManager extends AbstractHistoryManager {
|
|||
const message = await this.collection.findOne({ id: currentId })
|
||||
if (!message) break
|
||||
messages.unshift(message)
|
||||
currentId = message.parentMessageId
|
||||
currentId = message.parentId
|
||||
}
|
||||
return messages
|
||||
} else if (conversationId) {
|
||||
return this.collection.find({ conversationId })
|
||||
}
|
||||
return this.collection.findAll()
|
||||
return []
|
||||
}
|
||||
|
||||
async deleteConversation (conversationId) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
import { ChaiteStorage } from 'chaite'
|
||||
import * as crypto from 'node:crypto'
|
||||
|
||||
/**
|
||||
* 继承UserState
|
||||
*/
|
||||
export class YunzaiUserState {
|
||||
constructor (userId, nickname, card, conversationId = crypto.randomUUID()) {
|
||||
this.userId = userId
|
||||
this.nickname = nickname
|
||||
this.card = card
|
||||
this.conversations = []
|
||||
this.settings = {}
|
||||
this.current = {
|
||||
conversationId,
|
||||
messageId: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {ChaiteStorage<import('chaite').UserState>}
|
||||
|
|
@ -35,9 +53,12 @@ export class LowDBUserStateStorage extends ChaiteStorage {
|
|||
*/
|
||||
async setItem (id, state) {
|
||||
if (id) {
|
||||
await this.collection.updateById(id, state)
|
||||
return id
|
||||
if (await this.getItem(id)) {
|
||||
await this.collection.updateById(id, state)
|
||||
return id
|
||||
}
|
||||
}
|
||||
state.id = id
|
||||
const result = await this.collection.insert(state)
|
||||
return result.id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"type": "module",
|
||||
"author": "ikechan8370",
|
||||
"dependencies": {
|
||||
"chaite": "^1.2.1",
|
||||
"chaite": "^1.2.3",
|
||||
"js-yaml": "^4.1.0",
|
||||
"keyv": "^5.3.1",
|
||||
"keyv-file": "^5.1.2",
|
||||
|
|
|
|||
10
utils/bot.js
Normal file
10
utils/bot.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* 获取机器人框架
|
||||
* @returns {'trss'|'miao'}
|
||||
*/
|
||||
export function getBotFramework () {
|
||||
if (Bot.bots) {
|
||||
return 'trss'
|
||||
}
|
||||
return 'miao'
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { Chaite } from 'chaite'
|
||||
import common from '../../../lib/common/common.js'
|
||||
import ChatGPTConfig from '../config/config.js'
|
||||
import { getBotFramework } from './bot.js'
|
||||
/**
|
||||
* 模板
|
||||
* @param cmdPrefix
|
||||
|
|
@ -33,7 +34,7 @@ export function createCRUDCommandRules (cmdPrefix, name, variable, detail = true
|
|||
const manager = getManagerByName(upperVariable)
|
||||
if (detail) {
|
||||
rules.push({
|
||||
reg: cmdPrefix + `${name}详情$`,
|
||||
reg: cmdPrefix + `${name}详情`,
|
||||
fnc: `detail${upperVariable}`
|
||||
})
|
||||
this[`detail${upperVariable}`] = async function (e) {
|
||||
|
|
@ -130,6 +131,11 @@ export function createCRUDCommandRules (cmdPrefix, name, variable, detail = true
|
|||
}
|
||||
}
|
||||
}
|
||||
if (getBotFramework() === 'trss') {
|
||||
rules.forEach(rule => {
|
||||
rule.reg = new RegExp(rule.reg)
|
||||
})
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
|
|
@ -161,8 +167,12 @@ const switchCommandPreset = {
|
|||
}
|
||||
export function createSwitchCommandRules (cmdPrefix, name, variable, preset = 0) {
|
||||
const upperVariable = variable.charAt(0).toUpperCase() + variable.slice(1)
|
||||
return {
|
||||
const rule = {
|
||||
reg: cmdPrefix + `(${switchCommandPreset[preset][0]}|${switchCommandPreset[preset][1]})${name}$`,
|
||||
fnc: `switch${upperVariable}`
|
||||
}
|
||||
if (getBotFramework() === 'trss') {
|
||||
rule.reg = new RegExp(rule.reg)
|
||||
}
|
||||
return rule
|
||||
}
|
||||
|
|
|
|||
146
utils/group.js
Normal file
146
utils/group.js
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
import { getBotFramework } from './bot.js'
|
||||
import ChatGPTConfig from '../config/config.js'
|
||||
|
||||
export class GroupContextCollector {
|
||||
/**
|
||||
* 获取群组上下文
|
||||
* @param {*} bot bot实例
|
||||
* @param {string} groupId 群号
|
||||
* @param {number} start 起始seq
|
||||
* @param {number} length 往前数几条
|
||||
* @returns {Promise<Array<*>>}
|
||||
*/
|
||||
async collect (bot = Bot, groupId, start = 0, length = 20) {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
}
|
||||
|
||||
export class ICQQGroupContextCollector extends GroupContextCollector {
|
||||
/**
|
||||
* 获取群组上下文
|
||||
* @param {*} bot
|
||||
* @param {string} groupId
|
||||
* @param {number} start
|
||||
* @param {number} length
|
||||
* @returns {Promise<Array<*>>}
|
||||
*/
|
||||
async collect (bot = Bot, groupId, start = 0, length = 20) {
|
||||
const group = bot.pickGroup(groupId)
|
||||
let latestChats = await group.getChatHistory(start, 1)
|
||||
if (latestChats.length > 0) {
|
||||
let latestChat = latestChats[0]
|
||||
if (latestChat) {
|
||||
let seq = latestChat.seq || latestChat.message_id
|
||||
let chats = []
|
||||
while (chats.length < length) {
|
||||
let chatHistory = await group.getChatHistory(seq, 20)
|
||||
if (!chatHistory || chatHistory.length === 0) {
|
||||
break
|
||||
}
|
||||
chats.push(...chatHistory.reverse())
|
||||
if (seq === chatHistory[chatHistory.length - 1].seq || seq === chatHistory[chatHistory.length - 1].message_id) {
|
||||
break
|
||||
}
|
||||
seq = chatHistory[chatHistory.length - 1].seq || chatHistory[chatHistory.length - 1].message_id
|
||||
}
|
||||
chats = chats.slice(0, length).reverse()
|
||||
try {
|
||||
let mm = bot.gml
|
||||
for (const chat of chats) {
|
||||
let sender = mm.get(chat.sender.user_id)
|
||||
if (sender) {
|
||||
chat.sender = sender
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn(err)
|
||||
}
|
||||
// console.log(chats)
|
||||
return chats
|
||||
}
|
||||
}
|
||||
// }
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export class TRSSGroupContextCollector extends GroupContextCollector {
|
||||
/**
|
||||
* 获取群组上下文
|
||||
* @param {*} bot
|
||||
* @param {string} groupId
|
||||
* @param {number} start
|
||||
* @param {number} length
|
||||
* @returns {Promise<Array<*>>}
|
||||
*/
|
||||
async collect (bot = Bot, groupId, start = 0, length = 20) {
|
||||
const group = bot.pickGroup(groupId)
|
||||
let chats = await group.getChatHistory(start, length)
|
||||
try {
|
||||
let mm = bot.gml
|
||||
for (const chat of chats) {
|
||||
let sender = mm.get(chat.sender.user_id)
|
||||
if (sender) {
|
||||
chat.sender = sender
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn(err)
|
||||
}
|
||||
return chats
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取群组上下文
|
||||
* @param e
|
||||
* @param length
|
||||
* @returns {Promise<Array<*>>}
|
||||
*/
|
||||
export async function getGroupHistory (e, length = 20) {
|
||||
if (getBotFramework() === 'trss') {
|
||||
const collector = new TRSSGroupContextCollector()
|
||||
return await collector.collect(e.bot, e.group_id, 0, length)
|
||||
}
|
||||
return await new ICQQGroupContextCollector().collect(e.bot, e.group_id, 0, length)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取构建群聊聊天记录的prompt
|
||||
* @param e event
|
||||
* @param {number} length 长度
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function getGroupContextPrompt (e, length) {
|
||||
const {
|
||||
groupContextTemplatePrefix,
|
||||
groupContextTemplateMessage,
|
||||
groupContextTemplateSuffix
|
||||
} = ChatGPTConfig.llm
|
||||
const chats = await getGroupHistory(e, length)
|
||||
const rows = chats.map(chat => {
|
||||
const sender = chat.sender || {}
|
||||
return groupContextTemplateMessage
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.sender.card}', sender.card || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.sender.nickname}', sender.nickname || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.sender.user_id}', sender.user_id || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.sender.role}', sender.role || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.sender.title}', sender.title || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.time}', chat.time || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.messageId}', chat.messageId || '-')
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
.replace('${message.raw_message}', chat.raw_message || '-')
|
||||
}).join('\n')
|
||||
return [
|
||||
groupContextTemplatePrefix,
|
||||
rows,
|
||||
groupContextTemplateSuffix
|
||||
].join('\n')
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ export async function getPreset (e, presetId, toggleMode, togglePrefix) {
|
|||
const isValidChat = checkChatMsg(e, toggleMode, togglePrefix)
|
||||
const manager = Chaite.getInstance().getChatPresetManager()
|
||||
const presets = await manager.getAllPresets()
|
||||
const prefixHitPresets = presets.filter(p => e.msg.startsWith(p.prefix))
|
||||
const prefixHitPresets = presets.filter(p => e.msg?.startsWith(p.prefix))
|
||||
if (!isValidChat && prefixHitPresets.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue