Compare commits

..

No commits in common. "894dba0aa05b0ce5cc89c63c85e2167be2bb01e8" and "875ca65ed9c66c0a74936e0a517906cb2fa91208" have entirely different histories.

7 changed files with 18 additions and 59 deletions

View File

@ -115,8 +115,8 @@
- [X] 支持获取引用消息,使用seq标记 - [X] 支持获取引用消息,使用seq标记
- [X] 支持群聊上下文消息 - [X] 支持群聊上下文消息
- [ ] 支持调用更多工具 - [ ] 支持调用更多工具
- [X] 获取引用消息 - [ ] 获取引用消息
- [X] 适配多模态模型,查看图片等 - [ ] 适配多模态模型,查看图片等
- [ ] 支持联网搜索 - [ ] 支持联网搜索
- [ ] 支持生成图片 - [ ] 支持生成图片
- [ ] 支持渲染数学公式 - [ ] 支持渲染数学公式
@ -158,8 +158,7 @@
"faceReply": true, "faceReply": true,
"ai": true, "ai": true,
"blackWords": true, "blackWords": true,
"music": true, "music": true
"auth": true
} }
``` ```
</details> </details>
@ -260,10 +259,6 @@
"apiKey": "", //你的api密钥 "apiKey": "", //你的api密钥
"?modelType": "模型名称,请根据baseApi填写的服务商的对应的模型", "?modelType": "模型名称,请根据baseApi填写的服务商的对应的模型",
"modelType": "deepseek-ai/DeepSeek-V3.2-Exp", "modelType": "deepseek-ai/DeepSeek-V3.2-Exp",
"?multimodalEnabled": "是否启用多模态模型模式,启用后将忽略文本模型",//开启多模态模式后,将默认使用多模态模型回复
"multimodalEnabled": false,//多模态模式可以处理视频,图片等
"?multimodalModel": "多模态模型名称",
"multimodalModel": "Qwen/Qwen2.5-VL-72B-Instruct",
"?temperature": "聊天温度,可选0-2.0,温度越高创造性越高", "?temperature": "聊天温度,可选0-2.0,温度越高创造性越高",
"temperature": 1.2, "temperature": 1.2,
"?concurrency": "最大同时聊天群数,一个群最多一个人聊天", "?concurrency": "最大同时聊天群数,一个群最多一个人聊天",

View File

@ -76,6 +76,7 @@ Bot.on('message.group', async (e) => {
async function index(e) { async function index(e) {
try { try {
//logger.info('111')
const config = await ConfigControl.get(); const config = await ConfigControl.get();
const aiConfig = config?.ai; const aiConfig = config?.ai;
if (!config?.config?.ai) { if (!config?.config?.ai) {

View File

@ -13,6 +13,7 @@ export class FaceReply extends plugin {
} }
async accept(e) { async accept(e) {
if (!ConfigControl.get('config')?.faceReply) return;
if (!e.message_id || e.message.length === 0) return; if (!e.message_id || e.message.length === 0) return;
let face = []; let face = [];
e.message.forEach((m) => { e.message.forEach((m) => {

View File

@ -117,6 +117,9 @@ export default class FanqiePlugin extends plugin {
* 解析网页链接中的 book_id * 解析网页链接中的 book_id
*/ */
async handleFanqieLink(e) { async handleFanqieLink(e) {
if (!ConfigControl.get()?.config?.fanqie) {
return;
}
const message = e.msg.trim(); const message = e.msg.trim();
let bookId = null; let bookId = null;
@ -137,6 +140,9 @@ export default class FanqiePlugin extends plugin {
* 使用 #fq下载 命令下载 * 使用 #fq下载 命令下载
*/ */
async downloadByBookId(e) { async downloadByBookId(e) {
if (!ConfigControl.get()?.config?.fanqie) {
return;
}
const bookId = e.msg.replace(/^#?fq下载/, '').trim(); const bookId = e.msg.replace(/^#?fq下载/, '').trim();
return this.downloadFanqieBook(e, bookId); return this.downloadFanqieBook(e, bookId);
} }

View File

@ -21,7 +21,7 @@ export class CrystelfMusic extends plugin {
super({ super({
name: 'crystelf-music', name: 'crystelf-music',
dsc: '音乐点歌插件', dsc: '音乐点歌插件',
event: 'message', event: 'message.group',
priority: -1000, priority: -1000,
rule: [ rule: [
{ {

View File

@ -16,6 +16,5 @@
"faceReply": true, "faceReply": true,
"ai": true, "ai": true,
"blackWords": true, "blackWords": true,
"music": true, "music": true
"auth": true
} }

View File

@ -23,65 +23,22 @@ if(appConfig.autoUpdate) {
const appPath = Path.apps; const appPath = Path.apps;
const jsFiles = await fc.readDirRecursive(appPath, 'js'); const jsFiles = await fc.readDirRecursive(appPath, 'js');
const enabledApps = [];
const disabledApps = [];
for (const file of jsFiles) { let ret = jsFiles.map((file) => {
const name = file.replace('.js', '');
const configKey = getConfigKey(name);
if (appConfig[configKey] === false) {
disabledApps.push(name);
logger.info(`[crystelf-plugin] 插件 ${name} 已禁用,跳过加载`);
} else {
enabledApps.push(file);
}
}
if (disabledApps.length > 0) {
logger.info(`[crystelf-plugin] 已跳过 ${disabledApps.length} 个禁用的插件: ${disabledApps.join(', ')}`);
}
let ret = enabledApps.map((file) => {
return import(`./apps/${file}`); return import(`./apps/${file}`);
}); });
ret = await Promise.allSettled(ret); ret = await Promise.allSettled(ret);
let apps = {}; let apps = {};
for (let i in enabledApps) { for (let i in jsFiles) {
let name = enabledApps[i].replace('.js', ''); let name = jsFiles[i].replace('.js', '');
if (ret[i].status !== 'fulfilled') { if (ret[i].status !== 'fulfilled') {
logger.error(`[crystelf-plugin] 插件 ${name} 加载失败:`, ret[i].reason); logger.error(name, ret[i].reason);
continue; continue;
} }
apps[name] = ret[i].value[Object.keys(ret[i].value)[0]]; apps[name] = ret[i].value[Object.keys(ret[i].value)[0]];
} }
logger.info(`[crystelf-plugin] 成功加载 ${Object.keys(apps).length} 个插件`);
export { apps }; export { apps };
/**
* 将插件文件名映射到配置键名
* @param {string} fileName
* @returns {string}
*/
function getConfigKey(fileName) {
const keyMap = {
'60s': '60s',
'ai': 'ai',
'auth': 'auth',
'auth-set': 'auth',
'face-reply': 'faceReply',
'face-reply-message': 'faceReply',
'fanqie': 'fanqie',
'help': 'help',
'music': 'music',
'poke': 'poke',
'rssPush': 'rss',
'welcome': 'welcome',
'welcome-set': 'welcome',
'zwa': 'zwa'
};
return keyMap[fileName] || fileName;
}