koishi-plugin-aka-ai-generator 0.6.1 → 0.6.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.
- package/lib/index.js +78 -30
- 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
|
-
|
|
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
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
if (checkTimeout && checkTimeout()) break;
|
|
1608
|
+
const resultMessage = "图像处理完成!";
|
|
1609
|
+
taskLockReleased = true;
|
|
1610
|
+
setImmediate(async () => {
|
|
1587
1611
|
try {
|
|
1588
|
-
await
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1612
|
+
await recordUserUsage(session, styleName, images.length);
|
|
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.
|
|
1594
|
-
}
|
|
1595
|
-
|
|
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
|
-
|
|
1600
|
-
userManager.endTask(userId);
|
|
1638
|
+
throw error;
|
|
1601
1639
|
}
|
|
1602
1640
|
}
|
|
1603
1641
|
__name(processImage, "processImage");
|
|
@@ -1749,24 +1787,34 @@ Prompt: ${prompt}`);
|
|
|
1749
1787
|
if (resultImages.length === 0) {
|
|
1750
1788
|
return "图片合成失败:未能生成图片";
|
|
1751
1789
|
}
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
for (let i = 0; i < resultImages.length; i++) {
|
|
1755
|
-
if (isTimeout) break;
|
|
1790
|
+
const resultMessage = "图片合成完成!";
|
|
1791
|
+
setImmediate(async () => {
|
|
1756
1792
|
try {
|
|
1757
|
-
await
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1793
|
+
await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE, resultImages.length);
|
|
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.
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1809
|
+
logger.error(`异步发送合成图片时出错 (用户: ${userId}):`, err);
|
|
1810
|
+
} finally {
|
|
1811
|
+
userManager.endTask(userId);
|
|
1766
1812
|
}
|
|
1767
|
-
}
|
|
1768
|
-
|
|
1813
|
+
});
|
|
1814
|
+
return resultMessage;
|
|
1815
|
+
} catch (error) {
|
|
1769
1816
|
userManager.endTask(userId);
|
|
1817
|
+
throw error;
|
|
1770
1818
|
}
|
|
1771
1819
|
})(),
|
|
1772
1820
|
new Promise(
|