koishi-plugin-aka-ai-generator 0.6.1 → 0.6.5

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 +76 -28
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -1182,13 +1182,16 @@ var Config = import_koishi2.Schema.intersect([
1182
1182
  import_koishi2.Schema.const("gptgod").description("GPTGod 服务"),
1183
1183
  import_koishi2.Schema.const("gemini").description("Google Gemini 原生")
1184
1184
  ]).default("yunwu").description("图像生成供应商"),
1185
- yunwuApiKey: import_koishi2.Schema.string().description("云雾API密钥").role("secret").required(),
1185
+ // 所有字段都定义,但根据 provider 在运行时验证必填
1186
+ yunwuApiKey: import_koishi2.Schema.string().description("云雾API密钥").role("secret").default(""),
1186
1187
  yunwuModelId: import_koishi2.Schema.string().default("gemini-2.5-flash-image").description("云雾图像生成模型ID"),
1187
1188
  gptgodApiKey: import_koishi2.Schema.string().description("GPTGod API 密钥").role("secret").default(""),
1188
1189
  gptgodModelId: import_koishi2.Schema.string().default("nano-banana").description("GPTGod 模型ID"),
1189
1190
  geminiApiKey: import_koishi2.Schema.string().description("Gemini API 密钥").role("secret").default(""),
1190
1191
  geminiModelId: import_koishi2.Schema.string().default("gemini-2.5-flash").description("Gemini 模型ID"),
1191
- geminiApiBase: import_koishi2.Schema.string().default("https://generativelanguage.googleapis.com").description("Gemini API 基础地址"),
1192
+ geminiApiBase: import_koishi2.Schema.string().default("https://generativelanguage.googleapis.com").description("Gemini API 基础地址")
1193
+ }),
1194
+ import_koishi2.Schema.object({
1192
1195
  modelMappings: import_koishi2.Schema.array(import_koishi2.Schema.object({
1193
1196
  suffix: import_koishi2.Schema.string().required().description("指令后缀(例如 4K,对应输入 -4K)"),
1194
1197
  provider: import_koishi2.Schema.union([
@@ -1239,6 +1242,15 @@ var Config = import_koishi2.Schema.intersect([
1239
1242
  ]);
1240
1243
  function apply(ctx, config) {
1241
1244
  const logger = ctx.logger("aka-ai-generator");
1245
+ if (config.provider === "yunwu" && !config.yunwuApiKey) {
1246
+ throw new Error('当选择"云雾 Gemini 服务"时,云雾API密钥为必填项');
1247
+ }
1248
+ if (config.provider === "gptgod" && !config.gptgodApiKey) {
1249
+ throw new Error('当选择"GPTGod 服务"时,GPTGod API 密钥为必填项');
1250
+ }
1251
+ if (config.provider === "gemini" && !config.geminiApiKey) {
1252
+ throw new Error('当选择"Google Gemini 原生"时,Gemini API 密钥为必填项');
1253
+ }
1242
1254
  const userManager = new UserManager(ctx.baseDir, logger);
1243
1255
  function getProviderInstance(providerType, modelId) {
1244
1256
  return createImageProvider({
@@ -1514,13 +1526,18 @@ function apply(ctx, config) {
1514
1526
  if (!userManager.startTask(userId)) {
1515
1527
  return "您有一个图像处理任务正在进行中,请等待完成";
1516
1528
  }
1529
+ let taskLockReleased = false;
1517
1530
  try {
1518
1531
  const imageCount = requestContext?.numImages || config.defaultNumImages;
1519
1532
  if (imageCount < 1 || imageCount > 4) {
1533
+ userManager.endTask(userId);
1534
+ taskLockReleased = true;
1520
1535
  return "生成数量必须在 1-4 之间";
1521
1536
  }
1522
1537
  const inputResult = await getInputData(session, img, mode);
1523
1538
  if ("error" in inputResult) {
1539
+ userManager.endTask(userId);
1540
+ taskLockReleased = true;
1524
1541
  return inputResult.error;
1525
1542
  }
1526
1543
  if (checkTimeout && checkTimeout()) throw new Error("命令执行超时");
@@ -1534,17 +1551,23 @@ function apply(ctx, config) {
1534
1551
  await session.send("请发送画面描述");
1535
1552
  const promptMsg = await session.prompt(3e4);
1536
1553
  if (!promptMsg) {
1554
+ userManager.endTask(userId);
1555
+ taskLockReleased = true;
1537
1556
  return "未检测到描述,操作已取消";
1538
1557
  }
1539
1558
  const elements = import_koishi2.h.parse(promptMsg);
1540
1559
  const images2 = import_koishi2.h.select(elements, "img");
1541
1560
  if (images2.length > 0) {
1561
+ userManager.endTask(userId);
1562
+ taskLockReleased = true;
1542
1563
  return "检测到图片,本功能仅支持文字输入";
1543
1564
  }
1544
1565
  const text = import_koishi2.h.select(elements, "text").map((e) => e.attrs.content).join(" ").trim();
1545
1566
  if (text) {
1546
1567
  finalPrompt = text;
1547
1568
  } else {
1569
+ userManager.endTask(userId);
1570
+ taskLockReleased = true;
1548
1571
  return "未检测到有效文字描述,操作已取消";
1549
1572
  }
1550
1573
  }
@@ -1578,26 +1601,41 @@ ${infoParts.join("\n")}`;
1578
1601
  const images = await requestProviderImages(finalPrompt, imageUrls, imageCount, requestContext);
1579
1602
  if (checkTimeout && checkTimeout()) throw new Error("命令执行超时");
1580
1603
  if (images.length === 0) {
1604
+ userManager.endTask(userId);
1605
+ taskLockReleased = true;
1581
1606
  return "图像处理失败:未能生成图片";
1582
1607
  }
1583
1608
  await recordUserUsage(session, styleName, images.length);
1584
- await session.send("图像处理完成!");
1585
- for (let i = 0; i < images.length; i++) {
1586
- if (checkTimeout && checkTimeout()) break;
1609
+ const resultMessage = "图像处理完成!";
1610
+ taskLockReleased = true;
1611
+ setImmediate(async () => {
1587
1612
  try {
1588
- await Promise.race([
1589
- session.send(import_koishi2.h.image(images[i])),
1590
- new Promise((_, reject) => setTimeout(() => reject(new Error("SendTimeout")), 2e4))
1591
- ]);
1613
+ await session.send(resultMessage);
1614
+ for (let i = 0; i < images.length; i++) {
1615
+ try {
1616
+ await Promise.race([
1617
+ session.send(import_koishi2.h.image(images[i])),
1618
+ new Promise((_, reject) => setTimeout(() => reject(new Error("SendTimeout")), 2e4))
1619
+ ]);
1620
+ } catch (err) {
1621
+ logger.warn(`图片发送可能超时 (用户: ${userId}): ${err instanceof Error ? err.message : String(err)}`);
1622
+ }
1623
+ if (images.length > 1 && i < images.length - 1) {
1624
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1625
+ }
1626
+ }
1592
1627
  } catch (err) {
1593
- logger.warn(`图片发送可能超时 (用户: ${userId}): ${err instanceof Error ? err.message : String(err)}`);
1594
- }
1595
- if (images.length > 1 && i < images.length - 1) {
1596
- await new Promise((resolve) => setTimeout(resolve, 1e3));
1628
+ logger.error(`异步发送图片时出错 (用户: ${userId}):`, err);
1629
+ } finally {
1630
+ userManager.endTask(userId);
1597
1631
  }
1632
+ });
1633
+ return resultMessage;
1634
+ } catch (error) {
1635
+ if (!taskLockReleased) {
1636
+ userManager.endTask(userId);
1598
1637
  }
1599
- } finally {
1600
- userManager.endTask(userId);
1638
+ throw error;
1601
1639
  }
1602
1640
  }
1603
1641
  __name(processImage, "processImage");
@@ -1750,23 +1788,33 @@ Prompt: ${prompt}`);
1750
1788
  return "图片合成失败:未能生成图片";
1751
1789
  }
1752
1790
  await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE, resultImages.length);
1753
- await session.send("图片合成完成!");
1754
- for (let i = 0; i < resultImages.length; i++) {
1755
- if (isTimeout) break;
1791
+ const resultMessage = "图片合成完成!";
1792
+ setImmediate(async () => {
1756
1793
  try {
1757
- await Promise.race([
1758
- session.send(import_koishi2.h.image(resultImages[i])),
1759
- new Promise((_, reject) => setTimeout(() => reject(new Error("SendTimeout")), 2e4))
1760
- ]);
1794
+ await session.send(resultMessage);
1795
+ for (let i = 0; i < resultImages.length; i++) {
1796
+ try {
1797
+ await Promise.race([
1798
+ session.send(import_koishi2.h.image(resultImages[i])),
1799
+ new Promise((_, reject) => setTimeout(() => reject(new Error("SendTimeout")), 2e4))
1800
+ ]);
1801
+ } catch (err) {
1802
+ logger.warn(`图片合成发送可能超时 (用户: ${userId}): ${err instanceof Error ? err.message : String(err)}`);
1803
+ }
1804
+ if (resultImages.length > 1 && i < resultImages.length - 1) {
1805
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1806
+ }
1807
+ }
1761
1808
  } catch (err) {
1762
- logger.warn(`图片合成发送可能超时 (用户: ${userId}): ${err instanceof Error ? err.message : String(err)}`);
1763
- }
1764
- if (resultImages.length > 1 && i < resultImages.length - 1) {
1765
- await new Promise((resolve) => setTimeout(resolve, 1e3));
1809
+ logger.error(`异步发送合成图片时出错 (用户: ${userId}):`, err);
1810
+ } finally {
1811
+ userManager.endTask(userId);
1766
1812
  }
1767
- }
1768
- } finally {
1813
+ });
1814
+ return resultMessage;
1815
+ } catch (error) {
1769
1816
  userManager.endTask(userId);
1817
+ throw error;
1770
1818
  }
1771
1819
  })(),
1772
1820
  new Promise(
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.6.1",
4
+ "version": "0.6.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [