UNPKG

koishi-plugin-sus-chat

Version:
163 lines (162 loc) 6.46 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.apply = exports.logger = exports.usage = exports.Config = exports.name = void 0; const koishi_1 = require("koishi"); const chat_1 = require("./chat"); const js_yaml_1 = __importDefault(require("js-yaml")); const he_1 = __importDefault(require("he")); exports.name = "sus-chat"; var config_1 = require("./config"); Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } }); exports.usage = ` # 使用方法可查看: [**文档**](https://beradq.github.io/sus-chat-doc) `; class Collected { collected = {}; max_length; constructor(max_length) { this.max_length = max_length; } get(cid) { this.collected[cid]?.shift(); return this.collected[cid] ?? []; } add(cid, content) { this.collected[cid] = [...(this.collected[cid] ?? []), content]; while (this.collected[cid].length > this.max_length) { this.collected[cid].shift(); } } clean(cid) { this.collected[cid] = []; } } exports.logger = new koishi_1.Logger("sus-chat"); function apply(ctx, config) { const collected = new Collected(config.functionality.extension_count); const current_prompt = new CurrentPropmptName(config); const server = new chat_1.ChatServer(config, config.prompt.pro_prompt ? new chat_1.Prompts(ctx, config.prompt.prompt_directory, config) : config.prompt.prompt_str); server.persistence = config.functionality.persistence; if (config.functionality.persistence) server.load_recollect(ctx); async function chat(session, content) { const liquid = server.prompts?.get_liquid?.(ctx, session); const prompt_real = await server.get_prompt(current_prompt.get(session.cid), ctx, session); const my_content = prompt_real.postprocessing({ role: "user", content, }); const message = { role: "user", content: [...collected.get(session.cid), my_content.content].join("\n"), }; collected.clean(session.cid); const result = await server.chat(message, current_prompt.get(session.cid), ctx, session); return result?.content; } ctx.command("sus <content:text>", "与Ai聊天").action(async (s, content) => { return chat(s.session, content); }); if (config.prompt.pro_prompt) { ctx .command("sus.prom", "提示词相关指令,直接输入可查看提示词列表") .action(async (_s) => { return server.prompts.names .filter((v) => !v.startsWith(".")) .join("\n"); }); ctx .command("sus.prom.set <name:string>", "设置提示词") .action(async (s, name) => { if (!Object.keys(server.prompts.prompts_map).includes(name)) return "提示词不存在"; current_prompt.set(s.session.cid, name); return "设置成功"; }); ctx .command("sus.prom.exec <name:string>", "求值提示词") .action(async (s, name) => { const result = server.prompts.get(name, ctx, s.session); return js_yaml_1.default.dump(result.prompts); }); ctx.command("sus.prom.current", "查看当前提示词").action((s) => { return current_prompt.get(s.session.cid); }); ctx.command("sus.reload", "重新载入所有提示词").action(() => { server.prompts?.reload(ctx, config.prompt.prompt_directory); return "重载成功"; }); } ctx .command("sus.eval <content:text>", "求值 liquid") .action(async (s, content) => { const result = await server.evaluate(ctx, s.session, content); return result; }); ctx.command("sus.history", "查看聊天记录").action((s) => { return js_yaml_1.default.dump(server.get_recollect(s.session, current_prompt.get(s.session.cid))); }); ctx.command("sus.history.clean", "清空聊天记录").action((s) => { server.update_recollect(ctx, s.session, current_prompt.get(s.session.cid), (_) => []); collected.clean(s.session.cid); return "清空成功"; }); // 随机回复与关键词触发与私聊触发 ctx.middleware(async (session, next) => { const content = he_1.default.decode(session.content); if (!content) return next(); let for_key = false; let k1 = server.prompts?.get_keywords(current_prompt.get(session.cid)); let k2 = config.functionality.tiggering.keywords?.keywords_for_triggering; if (!(k1 instanceof Array)) k1 = []; if (!(k2 instanceof Array)) k2 = []; const keywords = [...k1, ...k2]; for (const key of keywords) { if (content.includes(key)) { for_key = true; break; } } const for_random = config.functionality.tiggering?.random_reply?.enable && Math.random() < config.functionality.tiggering?.random_reply?.probability; const for_direct = config.functionality.tiggering?.when_direct_reply && session?.isDirect; if (!(for_key || for_random || for_direct)) return next(); const result = await chat?.(session, content); return result ?? next(); }); if (config.functionality.extension_count >= 1) { ctx.middleware(async (session, next) => { const postprocessing = (await server?.get_prompt(current_prompt?.get(session.cid), ctx, session))?.postprocessing; const message = { role: "user", content: session.content, }; const result = postprocessing(message); collected?.add(session.cid, result?.content); return next(); }); } } exports.apply = apply; class CurrentPropmptName { current_name = {}; config; constructor(config) { this.config = config; } get(id) { return this.current_name[id] ?? this.config.prompt.default_prompt ?? ""; } set(id, name) { this.current_name[id] = name; } }