koishi-plugin-aka-ai-generator 0.4.0 → 0.4.2
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/index.js +77 -37
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -598,6 +598,39 @@ function parseGeminiResponse(response, logger) {
|
|
|
598
598
|
logger?.error("Gemini API 返回错误", { error: response.error });
|
|
599
599
|
throw new Error(`Gemini API 错误: ${response.error.message || JSON.stringify(response.error)}`);
|
|
600
600
|
}
|
|
601
|
+
if (response.promptFeedback) {
|
|
602
|
+
const blockReason = response.promptFeedback.blockReason;
|
|
603
|
+
const safetyRatings = response.promptFeedback.safetyRatings;
|
|
604
|
+
if (blockReason) {
|
|
605
|
+
logger?.error("Gemini API 请求被阻止", {
|
|
606
|
+
blockReason,
|
|
607
|
+
safetyRatings,
|
|
608
|
+
blockReasonMessage: response.promptFeedback.blockReasonMessage
|
|
609
|
+
});
|
|
610
|
+
let errorMessage = "请求被 Gemini API 阻止";
|
|
611
|
+
switch (blockReason) {
|
|
612
|
+
case "SAFETY":
|
|
613
|
+
errorMessage = "内容被安全策略阻止,可能包含不安全的内容";
|
|
614
|
+
break;
|
|
615
|
+
case "OTHER":
|
|
616
|
+
errorMessage = "请求被阻止(原因:OTHER),可能是内容不符合使用政策或模型无法处理";
|
|
617
|
+
if (response.promptFeedback.blockReasonMessage) {
|
|
618
|
+
errorMessage += `:${response.promptFeedback.blockReasonMessage}`;
|
|
619
|
+
}
|
|
620
|
+
break;
|
|
621
|
+
case "RECITATION":
|
|
622
|
+
errorMessage = "内容包含受版权保护的内容";
|
|
623
|
+
break;
|
|
624
|
+
default:
|
|
625
|
+
errorMessage = `请求被阻止(原因:${blockReason})`;
|
|
626
|
+
}
|
|
627
|
+
if (safetyRatings && Array.isArray(safetyRatings) && safetyRatings.length > 0) {
|
|
628
|
+
const ratings = safetyRatings.map((r) => `${r.category}:${r.probability}`).join(", ");
|
|
629
|
+
errorMessage += ` [安全评分: ${ratings}]`;
|
|
630
|
+
}
|
|
631
|
+
throw new Error(errorMessage);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
601
634
|
if (response.candidates && response.candidates.length > 0) {
|
|
602
635
|
for (const candidate of response.candidates) {
|
|
603
636
|
if (candidate.finishReason && candidate.finishReason !== "STOP") {
|
|
@@ -638,14 +671,29 @@ function parseGeminiResponse(response, logger) {
|
|
|
638
671
|
}
|
|
639
672
|
}
|
|
640
673
|
} else {
|
|
641
|
-
|
|
674
|
+
const hasPromptFeedback = !!response.promptFeedback;
|
|
675
|
+
const responseKeys = Object.keys(response);
|
|
676
|
+
logger?.error("Gemini API 响应中没有 candidates", {
|
|
677
|
+
response: JSON.stringify(response).substring(0, 500),
|
|
678
|
+
hasPromptFeedback,
|
|
679
|
+
responseKeys
|
|
680
|
+
});
|
|
681
|
+
if (!hasPromptFeedback) {
|
|
682
|
+
throw new Error("Gemini API 响应格式异常:既没有生成内容也没有反馈信息");
|
|
683
|
+
}
|
|
684
|
+
if (hasPromptFeedback && !response.promptFeedback.blockReason) {
|
|
685
|
+
logger?.warn("有 promptFeedback 但没有 blockReason,也没有 candidates", {
|
|
686
|
+
promptFeedback: response.promptFeedback
|
|
687
|
+
});
|
|
688
|
+
}
|
|
642
689
|
}
|
|
643
690
|
if (images.length === 0) {
|
|
644
691
|
logger?.error("未能从 Gemini API 响应中提取到任何图片", {
|
|
645
692
|
hasCandidates: !!response.candidates,
|
|
646
693
|
candidatesCount: response.candidates?.length || 0,
|
|
647
694
|
responseKeys: Object.keys(response),
|
|
648
|
-
firstCandidate: response.candidates?.[0] ? JSON.stringify(response.candidates[0]).substring(0, 300) : null
|
|
695
|
+
firstCandidate: response.candidates?.[0] ? JSON.stringify(response.candidates[0]).substring(0, 300) : null,
|
|
696
|
+
promptFeedback: response.promptFeedback ? JSON.stringify(response.promptFeedback) : null
|
|
649
697
|
});
|
|
650
698
|
}
|
|
651
699
|
return images;
|
|
@@ -1309,22 +1357,18 @@ function apply(ctx, config) {
|
|
|
1309
1357
|
return { images: [], text: imgParam.trim() };
|
|
1310
1358
|
}
|
|
1311
1359
|
await session.send("请输入画面描述");
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
if (!text) {
|
|
1323
|
-
await session.send("未检测到描述,请重新发送");
|
|
1324
|
-
continue;
|
|
1325
|
-
}
|
|
1326
|
-
return { images: [], text };
|
|
1360
|
+
const msg = await session.prompt(3e4);
|
|
1361
|
+
if (!msg) return { error: "等待超时" };
|
|
1362
|
+
const elements = import_koishi.h.parse(msg);
|
|
1363
|
+
const images = import_koishi.h.select(elements, "img");
|
|
1364
|
+
if (images.length > 0) {
|
|
1365
|
+
return { error: "检测到图片,本功能仅支持文字输入" };
|
|
1366
|
+
}
|
|
1367
|
+
const text = import_koishi.h.select(elements, "text").map((e) => e.attrs.content).join(" ").trim();
|
|
1368
|
+
if (!text) {
|
|
1369
|
+
return { error: "未检测到描述,操作已取消" };
|
|
1327
1370
|
}
|
|
1371
|
+
return { images: [], text };
|
|
1328
1372
|
}
|
|
1329
1373
|
if (imgParam) {
|
|
1330
1374
|
if (typeof imgParam === "object" && imgParam.attrs?.src) {
|
|
@@ -1379,8 +1423,7 @@ function apply(ctx, config) {
|
|
|
1379
1423
|
}
|
|
1380
1424
|
if (text) {
|
|
1381
1425
|
if (collectedImages.length === 0) {
|
|
1382
|
-
|
|
1383
|
-
continue;
|
|
1426
|
+
return { error: "未检测到图片,请重新发起指令并发送图片" };
|
|
1384
1427
|
}
|
|
1385
1428
|
collectedText = text;
|
|
1386
1429
|
break;
|
|
@@ -1438,23 +1481,20 @@ function apply(ctx, config) {
|
|
|
1438
1481
|
finalPrompt = finalPrompt.trim();
|
|
1439
1482
|
if (!finalPrompt) {
|
|
1440
1483
|
await session.send("请发送画面描述");
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
break;
|
|
1456
|
-
}
|
|
1457
|
-
await session.send("未检测到有效文字描述,请重新发送");
|
|
1484
|
+
const promptMsg = await session.prompt(3e4);
|
|
1485
|
+
if (!promptMsg) {
|
|
1486
|
+
return "未检测到描述,操作已取消";
|
|
1487
|
+
}
|
|
1488
|
+
const elements = import_koishi.h.parse(promptMsg);
|
|
1489
|
+
const images = import_koishi.h.select(elements, "img");
|
|
1490
|
+
if (images.length > 0) {
|
|
1491
|
+
return "检测到图片,本功能仅支持文字输入";
|
|
1492
|
+
}
|
|
1493
|
+
const text = import_koishi.h.select(elements, "text").map((e) => e.attrs.content).join(" ").trim();
|
|
1494
|
+
if (text) {
|
|
1495
|
+
finalPrompt = text;
|
|
1496
|
+
} else {
|
|
1497
|
+
return "未检测到有效文字描述,操作已取消";
|
|
1458
1498
|
}
|
|
1459
1499
|
}
|
|
1460
1500
|
const providerType = requestContext?.provider || config.provider;
|
|
@@ -1622,7 +1662,7 @@ ${infoParts.join("\n")}`;
|
|
|
1622
1662
|
prompt = text;
|
|
1623
1663
|
break;
|
|
1624
1664
|
}
|
|
1625
|
-
return "
|
|
1665
|
+
return "未检测到有效内容,操作已取消";
|
|
1626
1666
|
}
|
|
1627
1667
|
if (collectedImages.length < 2) {
|
|
1628
1668
|
return "需要至少两张图片进行合成,请重新发送";
|