koishi-plugin-best-cave 2.7.5 → 2.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,6 +30,8 @@ export declare class AIManager {
30
30
  private logger;
31
31
  private fileManager;
32
32
  private http;
33
+ private requestCount;
34
+ private rateLimitResetTime;
33
35
  /**
34
36
  * @constructor
35
37
  * @description AIManager 类的构造函数,负责初始化依赖项,并向 Koishi 的数据库模型中注册 `cave_meta` 表。
package/lib/index.d.ts CHANGED
@@ -61,6 +61,7 @@ export interface Config {
61
61
  aiEndpoint?: string;
62
62
  aiApiKey?: string;
63
63
  aiModel?: string;
64
+ aiTPM?: number;
64
65
  AnalysePrompt?: string;
65
66
  aiCheckPrompt?: string;
66
67
  aiAnalyseSchema?: string;
package/lib/index.js CHANGED
@@ -999,6 +999,8 @@ var AIManager = class {
999
999
  __name(this, "AIManager");
1000
1000
  }
1001
1001
  http;
1002
+ requestCount = 0;
1003
+ rateLimitResetTime = 0;
1002
1004
  /**
1003
1005
  * @description 注册所有与 AIManager 功能相关的 Koishi 命令。
1004
1006
  * @param {any} cave - 主 `cave` 命令的实例,用于在其下注册子命令。
@@ -1013,21 +1015,18 @@ var AIManager = class {
1013
1015
  if (cavesToAnalyze.length === 0) return "无需分析回声洞";
1014
1016
  await session.send(`开始分析 ${cavesToAnalyze.length} 个回声洞...`);
1015
1017
  let successCount = 0;
1016
- const batchSize = 100;
1017
- for (let i = 0; i < cavesToAnalyze.length; i += batchSize) {
1018
- const batch = cavesToAnalyze.slice(i, i + batchSize);
1019
- this.logger.info(`[${i}/${cavesToAnalyze.length}] 正在分析 ${batch.length} 条回声洞...`);
1020
- for (const cave2 of batch) {
1021
- try {
1022
- await this.analyzeAndStore(cave2);
1023
- successCount++;
1024
- } catch (error) {
1025
- this.logger.error(`分析回声洞(${cave2.id})时出错:`, error);
1026
- return `分析回声洞(${cave2.id})时出错: ${error.message}`;
1027
- }
1018
+ let failedCount = 0;
1019
+ for (const [index, cave2] of cavesToAnalyze.entries()) {
1020
+ this.logger.info(`[${index + 1}/${cavesToAnalyze.length}] 正在分析回声洞 (${cave2.id})...`);
1021
+ try {
1022
+ await this.analyzeAndStore(cave2);
1023
+ successCount++;
1024
+ } catch (error) {
1025
+ failedCount++;
1026
+ this.logger.error(`分析回声洞(${cave2.id})时出错:`, error);
1028
1027
  }
1029
1028
  }
1030
- return `已分析 ${successCount} 个回声洞`;
1029
+ return `已分析 ${successCount} 个回声洞(失败 ${failedCount} 个)`;
1031
1030
  } catch (error) {
1032
1031
  this.logger.error("分析回声洞失败:", error);
1033
1032
  return `操作失败: ${error.message}`;
@@ -1166,6 +1165,17 @@ var AIManager = class {
1166
1165
  * @throws {Error} 当 JSON Schema 解析失败、网络请求失败或 AI 返回错误时,抛出异常。
1167
1166
  */
1168
1167
  async requestAI(messages, systemPrompt, schemaString) {
1168
+ const now = Date.now();
1169
+ if (now > this.rateLimitResetTime) {
1170
+ this.rateLimitResetTime = now + 6e4;
1171
+ this.requestCount = 0;
1172
+ }
1173
+ if (this.requestCount >= this.config.aiTPM) {
1174
+ const delay = this.rateLimitResetTime - now;
1175
+ await new Promise((resolve) => setTimeout(resolve, delay));
1176
+ this.rateLimitResetTime = Date.now() + 6e4;
1177
+ this.requestCount = 0;
1178
+ }
1169
1179
  let schema = JSON.parse(schemaString);
1170
1180
  const payload = {
1171
1181
  model: this.config.aiModel,
@@ -1178,6 +1188,7 @@ var AIManager = class {
1178
1188
  "Authorization": `Bearer ${this.config.aiApiKey}`
1179
1189
  };
1180
1190
  try {
1191
+ this.requestCount++;
1181
1192
  const response = await this.http.post(fullUrl, payload, { headers, timeout: 9e4 });
1182
1193
  return JSON.parse(response.choices[0].message.content);
1183
1194
  } catch (error) {
@@ -1222,8 +1233,9 @@ var Config = import_koishi4.Schema.intersect([
1222
1233
  enableAI: import_koishi4.Schema.boolean().default(false).description("启用 AI"),
1223
1234
  aiEndpoint: import_koishi4.Schema.string().description("端点 (Endpoint)").role("link").default("https://generativelanguage.googleapis.com/v1beta/openai"),
1224
1235
  aiApiKey: import_koishi4.Schema.string().description("密钥 (Key)").role("secret"),
1225
- aiModel: import_koishi4.Schema.string().description("模型").default("gemini-2.5-flash"),
1226
- AnalysePrompt: import_koishi4.Schema.string().role("textarea").default(`你是一位内容分析专家。请分析我提供的内容,总结关键词,概括内容并进行评分。`).description("分析提示词 (Prompt)"),
1236
+ aiModel: import_koishi4.Schema.string().description("模型 (Model)").default("gemini-2.5-flash"),
1237
+ aiTPM: import_koishi4.Schema.number().description("每分钟请求数 (TPM)").default(60),
1238
+ AnalysePrompt: import_koishi4.Schema.string().role("textarea").default(`你是一位内容分析专家。请分析我提供的内容,总结关键词,概括内容并进行评分。`).description("分析 Prompt"),
1227
1239
  aiAnalyseSchema: import_koishi4.Schema.string().role("textarea").default(
1228
1240
  `{
1229
1241
  "type": "object",
@@ -1246,8 +1258,8 @@ var Config = import_koishi4.Schema.intersect([
1246
1258
  },
1247
1259
  "required": ["keywords", "description", "rating"]
1248
1260
  }`
1249
- ).description("分析输出模式 (JSON Schema)"),
1250
- aiCheckPrompt: import_koishi4.Schema.string().role("textarea").default(`你是一位内容查重专家。请判断我提供的"新内容"是否与"已有内容"重复或高度相似。`).description("查重提示词 (Prompt)"),
1261
+ ).description("分析 JSON Schema"),
1262
+ aiCheckPrompt: import_koishi4.Schema.string().role("textarea").default(`你是一位内容查重专家。请判断我提供的"新内容"是否与"已有内容"重复或高度相似。`).description("查重 Prompt"),
1251
1263
  aiCheckSchema: import_koishi4.Schema.string().role("textarea").default(
1252
1264
  `{
1253
1265
  "type": "object",
@@ -1263,7 +1275,7 @@ var Config = import_koishi4.Schema.intersect([
1263
1275
  },
1264
1276
  "required": ["duplicate"]
1265
1277
  }`
1266
- ).description("查重输出模式 (JSON Schema)")
1278
+ ).description("查重 JSON Schema")
1267
1279
  }).description("模型配置"),
1268
1280
  import_koishi4.Schema.object({
1269
1281
  localPath: import_koishi4.Schema.string().description("文件映射路径"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-best-cave",
3
3
  "description": "功能强大、高度可定制的回声洞。支持丰富的媒体类型、内容查重、人工审核、用户昵称、数据迁移以及本地/S3 双重文件存储后端。",
4
- "version": "2.7.5",
4
+ "version": "2.7.6",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],