koishi-plugin-best-cave 2.7.27 → 2.7.28
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.
- package/lib/AIManager.d.ts +0 -1
- package/lib/index.js +29 -35
- package/package.json +1 -1
package/lib/AIManager.d.ts
CHANGED
|
@@ -69,7 +69,6 @@ export declare class AIManager {
|
|
|
69
69
|
* @param {CaveObject} caveA - 第一个回声洞对象。
|
|
70
70
|
* @param {CaveObject} caveB - 第二个回声洞对象。
|
|
71
71
|
* @returns {Promise<boolean>} 如果内容被 AI 判断为重复,则返回 true,否则返回 false。
|
|
72
|
-
* @throws {Error} 当 AI 请求失败时抛出。
|
|
73
72
|
* @private
|
|
74
73
|
*/
|
|
75
74
|
private isContentDuplicateAI;
|
package/lib/index.js
CHANGED
|
@@ -1155,7 +1155,6 @@ var AIManager = class {
|
|
|
1155
1155
|
await session.send(`开始分析 ${cavesToAnalyze.length} 个回声洞...`);
|
|
1156
1156
|
let successCount = 0;
|
|
1157
1157
|
let failedCount = 0;
|
|
1158
|
-
let consecutiveFailures = 0;
|
|
1159
1158
|
for (let i = 0; i < cavesToAnalyze.length; i += 25) {
|
|
1160
1159
|
const batch = cavesToAnalyze.slice(i, i + 25);
|
|
1161
1160
|
this.logger.info(`[${i + 1}/${cavesToAnalyze.length}] 正在分析 ${batch.length} 个回声洞...`);
|
|
@@ -1167,10 +1166,8 @@ var AIManager = class {
|
|
|
1167
1166
|
const cave2 = batch[j];
|
|
1168
1167
|
if (result.status === "fulfilled" && result.value.length > 0) {
|
|
1169
1168
|
successfulAnalyses.push(result.value[0]);
|
|
1170
|
-
consecutiveFailures = 0;
|
|
1171
1169
|
} else {
|
|
1172
1170
|
failedCount++;
|
|
1173
|
-
consecutiveFailures++;
|
|
1174
1171
|
if (result.status === "rejected") this.logger.error(`分析回声洞(${cave2.id})失败:`, result.reason);
|
|
1175
1172
|
}
|
|
1176
1173
|
}
|
|
@@ -1178,7 +1175,6 @@ var AIManager = class {
|
|
|
1178
1175
|
await this.ctx.database.upsert("cave_meta", successfulAnalyses);
|
|
1179
1176
|
successCount += successfulAnalyses.length;
|
|
1180
1177
|
}
|
|
1181
|
-
if (consecutiveFailures >= 3) break;
|
|
1182
1178
|
}
|
|
1183
1179
|
return `已分析 ${successCount} 个回声洞(失败 ${failedCount} 个)`;
|
|
1184
1180
|
} catch (error) {
|
|
@@ -1194,8 +1190,12 @@ var AIManager = class {
|
|
|
1194
1190
|
if (allMeta.length < 2) return "无可比较数据";
|
|
1195
1191
|
const candidatePairs = generateFromLSH(allMeta, (meta) => ({ id: meta.cave, keys: meta.keywords }));
|
|
1196
1192
|
if (candidatePairs.size === 0) return "未发现相似内容";
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1193
|
+
const idsToCompare = /* @__PURE__ */ new Set();
|
|
1194
|
+
candidatePairs.forEach((pairKey) => {
|
|
1195
|
+
pairKey.split("-").map(Number).forEach((id) => idsToCompare.add(id));
|
|
1196
|
+
});
|
|
1197
|
+
const caveData = await this.ctx.database.get("cave", { id: { $in: Array.from(idsToCompare) }, status: "active" });
|
|
1198
|
+
const allCaves = new Map(caveData.map((c) => [c.id, c]));
|
|
1199
1199
|
const comparisonPromises = Array.from(candidatePairs).map(async (pairKey) => {
|
|
1200
1200
|
const [id1, id2] = pairKey.split("-").map(Number);
|
|
1201
1201
|
const cave1 = allCaves.get(id1);
|
|
@@ -1204,7 +1204,7 @@ var AIManager = class {
|
|
|
1204
1204
|
return null;
|
|
1205
1205
|
});
|
|
1206
1206
|
const results = await Promise.all(comparisonPromises);
|
|
1207
|
-
duplicatePairs
|
|
1207
|
+
const duplicatePairs = results.filter(Boolean);
|
|
1208
1208
|
if (duplicatePairs.length === 0) return "未发现高重复性的内容";
|
|
1209
1209
|
const dsu = new DSU();
|
|
1210
1210
|
const allIds = /* @__PURE__ */ new Set();
|
|
@@ -1295,12 +1295,14 @@ ${combinedText}` });
|
|
|
1295
1295
|
contentForAI.push(...images);
|
|
1296
1296
|
const userMessage = { role: "user", content: contentForAI };
|
|
1297
1297
|
const response = await this.requestAI([userMessage], this.ANALYSIS_SYSTEM_PROMPT);
|
|
1298
|
-
if (response)
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1298
|
+
if (response) {
|
|
1299
|
+
return {
|
|
1300
|
+
cave: cave.id,
|
|
1301
|
+
keywords: response.keywords || [],
|
|
1302
|
+
description: response.description || "",
|
|
1303
|
+
rating: Math.max(0, Math.min(100, response.rating || 0))
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1304
1306
|
return null;
|
|
1305
1307
|
});
|
|
1306
1308
|
const results = await Promise.all(analysisPromises);
|
|
@@ -1311,7 +1313,6 @@ ${combinedText}` });
|
|
|
1311
1313
|
* @param {CaveObject} caveA - 第一个回声洞对象。
|
|
1312
1314
|
* @param {CaveObject} caveB - 第二个回声洞对象。
|
|
1313
1315
|
* @returns {Promise<boolean>} 如果内容被 AI 判断为重复,则返回 true,否则返回 false。
|
|
1314
|
-
* @throws {Error} 当 AI 请求失败时抛出。
|
|
1315
1316
|
* @private
|
|
1316
1317
|
*/
|
|
1317
1318
|
async isContentDuplicateAI(caveA, caveB) {
|
|
@@ -1364,28 +1365,21 @@ ${combinedText}` });
|
|
|
1364
1365
|
"Content-Type": "application/json",
|
|
1365
1366
|
"Authorization": `Bearer ${this.config.aiApiKey}`
|
|
1366
1367
|
};
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
return JSON.parse(candidate);
|
|
1381
|
-
} catch (parseError) {
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
this.logger.error("解析失败", "原始响应:", JSON.stringify(response, null, 2));
|
|
1385
|
-
throw new Error();
|
|
1386
|
-
} catch (e) {
|
|
1387
|
-
throw e;
|
|
1368
|
+
const response = await this.http.post(fullUrl, payload, { headers, timeout: 6e5 });
|
|
1369
|
+
const content = response?.choices?.[0]?.message?.content;
|
|
1370
|
+
if (!content?.trim()) throw new Error();
|
|
1371
|
+
const candidates = [];
|
|
1372
|
+
const jsonBlockMatch = content.match(/```json\s*([\s\S]*?)\s*```/i);
|
|
1373
|
+
if (jsonBlockMatch && jsonBlockMatch[1]) candidates.push(jsonBlockMatch[1]);
|
|
1374
|
+
candidates.push(content);
|
|
1375
|
+
const firstBrace = content.indexOf("{");
|
|
1376
|
+
const lastBrace = content.lastIndexOf("}");
|
|
1377
|
+
if (firstBrace !== -1 && lastBrace > firstBrace) candidates.push(content.substring(firstBrace, lastBrace + 1));
|
|
1378
|
+
for (const candidate of [...new Set(candidates)]) try {
|
|
1379
|
+
return JSON.parse(candidate);
|
|
1380
|
+
} catch (parseError) {
|
|
1388
1381
|
}
|
|
1382
|
+
this.logger.error("原始响应:", JSON.stringify(response, null, 2));
|
|
1389
1383
|
}
|
|
1390
1384
|
};
|
|
1391
1385
|
|