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.
Files changed (2) hide show
  1. package/lib/index.js +77 -37
  2. 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
- logger?.warn("Gemini API 响应中没有 candidates", { response: JSON.stringify(response).substring(0, 500) });
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
- while (true) {
1313
- const msg = await session.prompt(3e4);
1314
- if (!msg) return { error: "等待超时" };
1315
- const elements = import_koishi.h.parse(msg);
1316
- const images = import_koishi.h.select(elements, "img");
1317
- if (images.length > 0) {
1318
- await session.send("检测到图片,请发送文字描述");
1319
- continue;
1320
- }
1321
- const text = import_koishi.h.select(elements, "text").map((e) => e.attrs.content).join(" ").trim();
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
- await session.send("未检测到图片,请先发送图片");
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
- while (true) {
1442
- const promptMsg = await session.prompt(3e4);
1443
- if (!promptMsg) {
1444
- return "未检测到描述,请重新发送";
1445
- }
1446
- const elements = import_koishi.h.parse(promptMsg);
1447
- const images = import_koishi.h.select(elements, "img");
1448
- if (images.length > 0) {
1449
- await session.send("检测到图片,请发送文字描述");
1450
- continue;
1451
- }
1452
- const text = import_koishi.h.select(elements, "text").map((e) => e.attrs.content).join(" ").trim();
1453
- if (text) {
1454
- finalPrompt = text;
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 "需要至少两张图片进行合成,请重新发送";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-aka-ai-generator",
3
3
  "description": "自用AI生成插件(GPTGod & Yunwu)",
4
- "version": "0.4.0",
4
+ "version": "0.4.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [