@rinkuto/koishi-plugin-chatgpt
Version:
使用open ai的gpt-3.5-turbo模型
209 lines (208 loc) • 9.92 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.apply = exports.name = void 0;
const jsx_runtime_1 = require("@satorijs/element/jsx-runtime");
const koishi_1 = require("koishi");
const AskChatGPT_1 = require("./util/AskChatGPT");
const BingSearch_1 = require("./search/BingSearch");
const ChatGptKeyWord_1 = require("./keyword/ChatGptKeyWord");
const TencentKeyWord_1 = require("./keyword/TencentKeyWord");
const BaiduSearch_1 = require("./search/BaiduSearch");
const GoogleSearch_1 = require("./search/GoogleSearch");
const PuppeteerUtil_1 = require("./util/PuppeteerUtil");
const Memory_1 = require("./Memory");
exports.name = 'chatgpt';
__exportStar(require("./Config"), exports);
// 以后可以考虑加入更多的搜索引擎
const searchContent = new Map();
const keyWordsContent = new Map();
// 获取回复类型
const getReplyType = (session, config) => {
if (session.subtype === 'private') { // 私聊
return 0;
}
else {
if (session.parsed.appel === true) { // 被@了
return 1;
}
if (session.content.includes(config.botName)) { // 包含机器人名字
return 2;
}
if (koishi_1.Random.bool(config.replyRate)) { // 随机回复
return 3;
}
return -1;
}
};
let _logger;
function apply(ctx, config) {
_logger = ctx.logger('chatgpt');
// ctx.plugin('puppeteer');
// write your plugin here
Memory_1.MemoryManager.setConfig(config);
AskChatGPT_1.AskChatGPT.setConfig(config);
AskChatGPT_1.AskChatGPT.setHttp(ctx.http);
initSearchContent(ctx.http, config);
initKeyWordsContent(ctx.http, config);
ctx.middleware(async (session, next) => {
if (ctx.bots[session.userId]) {
return;
}
const replyType = getReplyType(session, config);
if (replyType === -1) {
return;
}
const input = session.content.replace(/<[^>]*>/g, '').trim();
if (input === '') {
return;
}
if (config.isLog) {
_logger.info(`receive ${session.username} message:${input}`);
}
const isPerson = session.subtype === 'private' || config.contextType === 'person';
if (Memory_1.MemoryManager.getMemory(isPerson ? session.userId : session.guildId, isPerson) === undefined) {
Memory_1.MemoryManager.createUserMemory(session.userId, session.username, isPerson ? undefined : session.guildId);
if (config.isLog) {
_logger.info('认识了新朋友:', session.username);
}
}
const memories = Memory_1.MemoryManager.getMemory(isPerson ? session.userId : session.guildId, isPerson);
let messages = AskChatGPT_1.AskChatGPT.createRequestMessages(memories);
// if (config.isDebug) {
// _logger.info(`keyWordType:${config.keyWordType}`);
// _logger.info(`searchType:${config.searchType}`);
// _logger.info(`isUseSearch:${config.isUseSearch}`);
// _logger.info(`isImage:${config.isImage}`);
// }
// 获取关键词,通过关键词搜索
const time = new Date().getTime();
if (config.isUseSearch) {
const keyWordUtil = keyWordsContent.get(config.keyWordType);
const keyWords = await keyWordUtil.getKeyWords(input);
if (config.isLog) {
_logger.info(`keyWords:${keyWords}`);
}
if (keyWords.trim() !== undefined && keyWords.trim() !== '' && keyWords.trim()[0] !== '无') {
const Search = searchContent.get(config.searchType);
const search = await Search.search(keyWords.trim().split(' '));
if (config.isDebug) {
_logger.info(`search:${search}`);
}
if (search !== undefined && search.length > 0) {
messages = AskChatGPT_1.AskChatGPT.createRequestMessages(memories, search);
}
}
}
const time2 = new Date().getTime();
// 将用户输入添加到消息队列
messages.push(AskChatGPT_1.AskChatGPT.setUserPrompt({
content: input,
name: session.username,
userId: session.userId
}, isPerson));
// 回复
AskChatGPT_1.AskChatGPT.askChatGPT(messages).then(reply => {
replyMethod(replyType, reply, session, config, ctx).then(async () => {
if (config.isLog) {
_logger.info(`reply ${session.username} ${isPerson ? '' : '[Group:' + session.guildId + ']'} [${config.isImage && ctx?.puppeteer ? 'image' : 'text'}]:${reply}`);
}
memories.addMemory(session.userId, session.username, { user: input, bot: reply });
}).catch((e) => {
_logger.error('reply error:', e);
}).finally(() => {
const time3 = new Date().getTime();
if (config.isDebug) {
_logger.info(`搜索关键词耗时:${time2 - time}ms,请求OpenAi耗时:${time3 - time2}ms`);
}
});
}).catch((e) => {
_logger.error(e);
if (e.response?.status === undefined) {
replyMethod(replyType, `请求失败,请稍后再试\nerror code: ${e.syscall} ${e.code}`, session, config);
}
else {
replyMethod(replyType, `请求失败,请稍后再试\nerror code: ${e.response.status}`, session, config);
}
});
return await next();
});
ctx.command('reset', '删除关于你的记忆')
.alias('重置')
.action(async ({ session }) => {
const isPerson = session.subtype === 'private' || config.contextType === 'person';
Memory_1.MemoryManager.clearMemory(isPerson ? session.userId : session.guildId, isPerson);
if (config.isLog) {
_logger.info('reset memory:', session.username, '');
}
await replyMethod(getReplyType(session, config), '记忆已重置', session, config);
});
ctx.command('balance', '查询余额')
.alias('余额')
.action(async ({ session }) => {
const balance = await AskChatGPT_1.AskChatGPT.getBalance();
await replyMethod(getReplyType(session, config), `余额:$${balance.total_used.toFixed(2)} / $${balance.total_granted.toFixed(2)}\n已用 ${(balance.total_used / balance.total_granted * 100).toFixed(2)}%`, session, config);
});
ctx.using(['puppeteer'], (ctx) => {
ctx.middleware(async (session, next) => {
return await next();
});
});
}
exports.apply = apply;
// 回复方法
const replyMethod = async (replyType, replyText, session, config, ctx) => {
const message = await replyMessage(replyType, replyText, session, config, ctx);
return session.send(message).then(res => {
if (res.length === 0) {
replyMethod(replyType, '回复失败', session, config);
}
});
};
// 回复的信息
const replyMessage = async (replyType, replyText, session, config, ctx) => {
// 如果是私聊 或者不需要at
if (replyType === 0 || config.isAt === false) {
// 如果开启了puppeteer并且puppeteer已经启动
if (config.isImage && ctx?.puppeteer) {
const message = await PuppeteerUtil_1.PuppeteerUtil.getInstance(ctx).getHtml(replyText);
if (config.isDebug) {
_logger.info(`image url:${message.substring(0, 200)}...`, message.length);
}
return (0, jsx_runtime_1.jsx)("image", { url: message });
}
return replyText;
}
else { // 是群聊
if (config.isImage && ctx?.puppeteer) { // 如果开启了puppeteer并且puppeteer已经启动
const message = await PuppeteerUtil_1.PuppeteerUtil.getInstance(ctx).getHtml(replyText);
if (config.isDebug) {
_logger.info(`image url:${message.substring(0, 200)}...`, message.length);
}
return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("at", { id: session.userId }), (0, jsx_runtime_1.jsx)("image", { url: message })] });
}
return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("at", { id: session.userId }), (0, jsx_runtime_1.jsx)("text", { content: replyText })] });
}
};
const initSearchContent = (http, config) => {
searchContent.set('bing', new BingSearch_1.BingSearch(http, config));
searchContent.set('baidu', new BaiduSearch_1.BaiduSearch(http, config));
searchContent.set('google', new GoogleSearch_1.GoogleSearch(http, config));
};
const initKeyWordsContent = (http, config) => {
keyWordsContent.set('chatgpt', new ChatGptKeyWord_1.ChatGptKeyWord(http, config));
keyWordsContent.set('tencent', new TencentKeyWord_1.TencentKeyWord(http, config));
};