UNPKG

koishi-plugin-yesimbot-extension-online-prompt

Version:

YesImBot 在线提示词加载扩展,由AI完成编写,不保证可靠性,可能出现奇怪问题

230 lines (223 loc) 9.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Config = exports.usage = exports.using = exports.inject = exports.name = void 0; exports.default = apply; const koishi_1 = require("koishi"); exports.name = "yesimbot-extension-online-prompt"; exports.inject = ["yesimbot", "http"]; exports.using = ["yesimbot", "http"]; exports.usage = ` ## 📖 使用说明 本插件为 YesImBot 提供在线提示词加载功能,支持从多个在线源动态获取自定义提示词。 ### 🌟 主要特性 - 支持多个在线提示词源 - 自动缓存和刷新机制 - 优先级控制和条件启用 - 支持自定义 HTTP 请求头 - 错误重试和超时控制 ### 🔧 配置说明 #### 基本配置 1. **添加提示词源**:点击"添加项目"按钮 2. **填写必要信息**: - 名称:为提示词源起一个便于识别的名称 - URL:提示词内容的完整 URL 地址 - 优先级:数字越小优先级越高(默认:10) - 启用状态:是否启用此提示词源 #### 高级配置 - **刷新间隔**:自动刷新提示词的时间间隔(秒),设为 0 禁用自动刷新 - **请求超时**:HTTP 请求的超时时间(秒) - **重试次数**:请求失败时的重试次数 - **缓存设置**:启用缓存可提高性能,设置缓存过期时间 ### 📝 支持的 URL 格式 - GitHub Gist Raw URL - Notion 页面导出链接 - 任何返回纯文本的 HTTP(S) URL ### ⚠️ 注意事项 - 确保 URL 返回的是纯文本格式的提示词内容 - 建议设置合理的刷新间隔,避免频繁请求 - 如需认证,可在"请求头"中添加相应的认证信息 `; exports.Config = koishi_1.Schema.object({ urls: koishi_1.Schema.array(koishi_1.Schema.object({ name: koishi_1.Schema.string().required().description("提示词源的名称"), url: koishi_1.Schema.string().required().description("提示词内容的 URL(支持 GitHub Gist raw URL、Notion 导出链接等)"), priority: koishi_1.Schema.number().default(10).description("优先级,数字越小越靠前"), enabled: koishi_1.Schema.boolean().default(true).description("是否启用此提示词源"), headers: koishi_1.Schema.dict(koishi_1.Schema.string()).description("可选的 HTTP 请求头"), })) .default([]) .description("在线提示词源配置列表"), refreshInterval: koishi_1.Schema.number().default(300).description("刷新间隔(秒),0 表示不自动刷新"), timeout: koishi_1.Schema.number().default(10).description("请求超时时间(秒)"), retryAttempts: koishi_1.Schema.number().default(3).description("请求失败时的重试次数"), enableCache: koishi_1.Schema.boolean().default(true).description("是否启用缓存"), cacheExpiry: koishi_1.Schema.number().default(3600).description("缓存过期时间(秒)"), }); /** * 在线提示词加载扩展 * 支持从多个在线源(如 GitHub Gist、Notion 等)动态加载自定义提示词 */ class OnlinePromptExtension { constructor(ctx, config) { this.ctx = ctx; this.config = config; this.cache = new Map(); this.logger = ctx.logger("online-prompt-extension"); // 在 ready 事件中执行异步初始化逻辑 this.ctx.on("ready", () => this.onMount()); this.ctx.on("dispose", () => this.onDispose()); } /** * 扩展挂载时的生命周期钩子 */ async onMount() { // 按优先级排序 this.config.urls.sort((a, b) => a.priority - b.priority); this.logger.info("在线提示词源已按优先级排序"); this.ctx.scope.update(this.config, false); // 注入 PromptService const promptService = this.ctx.get('yesimbot')?.prompt; if (!promptService) { this.logger.error('YesImBot 服务未找到,请确保已安装并启用 koishi-plugin-yesimbot'); return; } // 为每个启用的提示词源注册一个片段 for (const urlConfig of this.config.urls) { if (!urlConfig.enabled) continue; const snippetKey = `online.${urlConfig.name}`; promptService.inject({ key: snippetKey, priority: urlConfig.priority, render: async () => { try { const content = await this.fetchPromptContent(urlConfig); return content || ""; } catch (error) { this.logger.error(`获取在线提示词 "${urlConfig.name}" 失败:`, error); return ""; } } }); this.logger.info(`已注册在线提示词片段: {{${snippetKey}}}`); } // 设置自动刷新 if (this.config.refreshInterval > 0) { this.refreshTimer = setInterval(() => { this.refreshCache(); }, this.config.refreshInterval * 1000); this.logger.info(`已启用自动刷新,间隔 ${this.config.refreshInterval} 秒`); } // 预加载所有提示词内容 await this.preloadAllPrompts(); this.logger.info("在线提示词加载扩展已启动"); } /** * 扩展卸载时的生命周期钩子 */ onDispose() { if (this.refreshTimer) { clearInterval(this.refreshTimer); this.refreshTimer = undefined; } this.cache.clear(); this.logger.info("在线提示词加载扩展已卸载"); } /** * 获取提示词内容 */ async fetchPromptContent(urlConfig) { const cacheKey = `${urlConfig.name}_${urlConfig.url}`; // 检查缓存 if (this.config.enableCache && this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); const isExpired = Date.now() - cached.timestamp > this.config.cacheExpiry * 1000; if (!isExpired) { this.logger.debug(`使用缓存的提示词内容: ${urlConfig.name}`); return cached.content; } } // 从网络获取 let lastError = null; for (let attempt = 1; attempt <= this.config.retryAttempts; attempt++) { try { this.logger.debug(`正在获取提示词内容: ${urlConfig.name} (尝试 ${attempt}/${this.config.retryAttempts})`); const response = await this.ctx.http.get(urlConfig.url, { timeout: this.config.timeout * 1000, headers: { 'User-Agent': 'YesImBot-OnlinePrompt/1.0.0', ...urlConfig.headers, }, }); if (typeof response !== 'string') { throw new Error('响应不是文本格式'); } const content = response.trim(); // 更新缓存 if (this.config.enableCache) { this.cache.set(cacheKey, { content, timestamp: Date.now(), }); } this.logger.info(`成功获取提示词内容: ${urlConfig.name} (${content.length} 字符)`); return content; } catch (error) { lastError = error; this.logger.warn(`获取提示词内容失败 (尝试 ${attempt}/${this.config.retryAttempts}): ${urlConfig.name} - ${error.message}`); if (attempt < this.config.retryAttempts) { // 等待一段时间后重试 await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); } } } // 所有重试都失败了,返回缓存内容(如果有的话) if (this.config.enableCache && this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); this.logger.warn(`使用过期缓存的提示词内容: ${urlConfig.name}`); return cached.content; } throw lastError || new Error('未知错误'); } /** * 预加载所有提示词内容 */ async preloadAllPrompts() { const promises = this.config.urls .filter(url => url.enabled) .map(async (urlConfig) => { try { await this.fetchPromptContent(urlConfig); } catch (error) { this.logger.error(`预加载提示词失败: ${urlConfig.name} - ${error.message}`); } }); await Promise.all(promises); this.logger.info("提示词预加载完成"); } /** * 刷新缓存 */ async refreshCache() { this.logger.debug("开始刷新提示词缓存"); // 清除过期缓存 const now = Date.now(); for (const [key, cached] of this.cache.entries()) { if (now - cached.timestamp > this.config.cacheExpiry * 1000) { this.cache.delete(key); } } // 重新加载所有提示词 await this.preloadAllPrompts(); } } /** * 插件主函数 */ function apply(ctx, config) { new OnlinePromptExtension(ctx, config); } //# sourceMappingURL=index.js.map