koishi-plugin-aka-ai-generator 0.6.10 → 0.6.12
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 +310 -36
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -410,18 +410,60 @@ var GptGodProvider = class {
|
|
|
410
410
|
throw new Error(`生成失败:${shortError}`);
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
|
+
logger.debug("开始流式处理图片 (GPTGod)", {
|
|
414
|
+
imagesCount: images.length,
|
|
415
|
+
hasCallback: !!onImageGenerated,
|
|
416
|
+
current: i + 1,
|
|
417
|
+
total: numImages
|
|
418
|
+
});
|
|
413
419
|
for (let imgIdx = 0; imgIdx < images.length; imgIdx++) {
|
|
414
420
|
const imageUrl = images[imgIdx];
|
|
415
421
|
const currentIndex = allImages.length;
|
|
416
422
|
allImages.push(imageUrl);
|
|
423
|
+
logger.debug("准备处理单张图片 (GPTGod)", {
|
|
424
|
+
imgIdx,
|
|
425
|
+
currentIndex,
|
|
426
|
+
total: numImages,
|
|
427
|
+
imageUrlType: typeof imageUrl,
|
|
428
|
+
imageUrlLength: imageUrl?.length || 0,
|
|
429
|
+
imageUrlPrefix: imageUrl?.substring(0, 50) || "null"
|
|
430
|
+
});
|
|
417
431
|
if (onImageGenerated) {
|
|
432
|
+
logger.info("准备调用图片生成回调函数 (GPTGod)", {
|
|
433
|
+
hasCallback: true,
|
|
434
|
+
currentIndex,
|
|
435
|
+
total: numImages,
|
|
436
|
+
imageUrlLength: imageUrl?.length || 0
|
|
437
|
+
});
|
|
418
438
|
try {
|
|
419
439
|
await onImageGenerated(imageUrl, currentIndex, numImages);
|
|
440
|
+
logger.info("图片生成回调函数执行成功 (GPTGod)", {
|
|
441
|
+
currentIndex,
|
|
442
|
+
total: numImages,
|
|
443
|
+
imageUrlLength: imageUrl?.length || 0
|
|
444
|
+
});
|
|
420
445
|
} catch (callbackError) {
|
|
421
|
-
logger.
|
|
446
|
+
logger.error("图片生成回调函数执行失败 (GPTGod)", {
|
|
447
|
+
error: sanitizeError(callbackError),
|
|
448
|
+
errorMessage: callbackError?.message,
|
|
449
|
+
errorStack: callbackError?.stack,
|
|
450
|
+
currentIndex,
|
|
451
|
+
total: numImages,
|
|
452
|
+
imageUrlLength: imageUrl?.length || 0
|
|
453
|
+
});
|
|
422
454
|
}
|
|
455
|
+
} else {
|
|
456
|
+
logger.warn("图片生成回调函数未提供,跳过流式发送 (GPTGod)", {
|
|
457
|
+
currentIndex,
|
|
458
|
+
total: numImages,
|
|
459
|
+
imageUrlLength: imageUrl?.length || 0
|
|
460
|
+
});
|
|
423
461
|
}
|
|
424
462
|
}
|
|
463
|
+
logger.debug("流式处理图片完成 (GPTGod)", {
|
|
464
|
+
processedCount: images.length,
|
|
465
|
+
allImagesCount: allImages.length
|
|
466
|
+
});
|
|
425
467
|
logger.success("GPTGod 图像编辑 API 调用成功", { current: i + 1, total: numImages });
|
|
426
468
|
success = true;
|
|
427
469
|
break;
|
|
@@ -492,6 +534,11 @@ var GptGodProvider = class {
|
|
|
492
534
|
function parseGeminiResponse(response, logger) {
|
|
493
535
|
try {
|
|
494
536
|
const images = [];
|
|
537
|
+
logger?.debug("开始解析 Gemini API 响应", {
|
|
538
|
+
hasResponse: !!response,
|
|
539
|
+
responseType: typeof response,
|
|
540
|
+
responseKeys: response ? Object.keys(response) : []
|
|
541
|
+
});
|
|
495
542
|
if (!response) {
|
|
496
543
|
logger?.error("Gemini API 响应为空");
|
|
497
544
|
return [];
|
|
@@ -537,7 +584,16 @@ function parseGeminiResponse(response, logger) {
|
|
|
537
584
|
}
|
|
538
585
|
}
|
|
539
586
|
if (response.candidates && response.candidates.length > 0) {
|
|
540
|
-
|
|
587
|
+
logger?.debug("找到 candidates", { candidatesCount: response.candidates.length });
|
|
588
|
+
for (let candIdx = 0; candIdx < response.candidates.length; candIdx++) {
|
|
589
|
+
const candidate = response.candidates[candIdx];
|
|
590
|
+
logger?.debug("处理 candidate", {
|
|
591
|
+
index: candIdx,
|
|
592
|
+
hasContent: !!candidate.content,
|
|
593
|
+
hasParts: !!candidate.content?.parts,
|
|
594
|
+
partsCount: candidate.content?.parts?.length || 0,
|
|
595
|
+
finishReason: candidate.finishReason
|
|
596
|
+
});
|
|
541
597
|
if (candidate.finishReason && candidate.finishReason !== "STOP") {
|
|
542
598
|
logger?.warn("Gemini 响应 finishReason 异常", {
|
|
543
599
|
finishReason: candidate.finishReason,
|
|
@@ -551,28 +607,67 @@ function parseGeminiResponse(response, logger) {
|
|
|
551
607
|
}
|
|
552
608
|
}
|
|
553
609
|
if (candidate.content && candidate.content.parts) {
|
|
554
|
-
|
|
610
|
+
logger?.debug("处理 candidate.content.parts", {
|
|
611
|
+
partsCount: candidate.content.parts.length,
|
|
612
|
+
partsKeys: candidate.content.parts.map((p) => Object.keys(p))
|
|
613
|
+
});
|
|
614
|
+
for (let partIdx = 0; partIdx < candidate.content.parts.length; partIdx++) {
|
|
615
|
+
const part = candidate.content.parts[partIdx];
|
|
616
|
+
const partKeys = Object.keys(part);
|
|
617
|
+
logger?.debug("处理 part", {
|
|
618
|
+
partIndex: partIdx,
|
|
619
|
+
partKeys,
|
|
620
|
+
hasInlineData: !!part.inlineData,
|
|
621
|
+
hasInline_data: !!part.inline_data,
|
|
622
|
+
hasFileData: !!part.fileData,
|
|
623
|
+
hasText: !!part.text
|
|
624
|
+
});
|
|
555
625
|
if (part.inlineData && part.inlineData.data) {
|
|
556
626
|
const base64Data = part.inlineData.data;
|
|
557
627
|
const mimeType = part.inlineData.mimeType || "image/jpeg";
|
|
558
628
|
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
559
629
|
images.push(dataUrl);
|
|
560
|
-
logger?.
|
|
630
|
+
logger?.info("从响应中提取到图片 (inlineData)", {
|
|
631
|
+
mimeType,
|
|
632
|
+
dataLength: base64Data.length,
|
|
633
|
+
dataUrlLength: dataUrl.length,
|
|
634
|
+
imageIndex: images.length - 1
|
|
635
|
+
});
|
|
561
636
|
} else if (part.inline_data && part.inline_data.data) {
|
|
562
637
|
const base64Data = part.inline_data.data;
|
|
563
638
|
const mimeType = part.inline_data.mime_type || "image/jpeg";
|
|
564
639
|
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
565
640
|
images.push(dataUrl);
|
|
566
|
-
logger?.
|
|
641
|
+
logger?.info("从响应中提取到图片 (inline_data)", {
|
|
642
|
+
mimeType,
|
|
643
|
+
dataLength: base64Data.length,
|
|
644
|
+
dataUrlLength: dataUrl.length,
|
|
645
|
+
imageIndex: images.length - 1
|
|
646
|
+
});
|
|
567
647
|
} else if (part.fileData && part.fileData.fileUri) {
|
|
568
648
|
images.push(part.fileData.fileUri);
|
|
569
|
-
logger?.
|
|
649
|
+
logger?.info("从响应中提取到图片 (fileData)", {
|
|
650
|
+
fileUri: part.fileData.fileUri,
|
|
651
|
+
imageIndex: images.length - 1
|
|
652
|
+
});
|
|
570
653
|
} else if (part.text) {
|
|
571
|
-
logger?.warn("响应中包含文本而非图片", {
|
|
654
|
+
logger?.warn("响应中包含文本而非图片", {
|
|
655
|
+
text: part.text.substring(0, 100),
|
|
656
|
+
textLength: part.text.length
|
|
657
|
+
});
|
|
658
|
+
} else {
|
|
659
|
+
logger?.warn("part 中没有找到图片或文本数据", {
|
|
660
|
+
partKeys,
|
|
661
|
+
part: JSON.stringify(part).substring(0, 200)
|
|
662
|
+
});
|
|
572
663
|
}
|
|
573
664
|
}
|
|
574
665
|
} else {
|
|
575
|
-
logger?.warn("候选响应中没有 content.parts", {
|
|
666
|
+
logger?.warn("候选响应中没有 content.parts", {
|
|
667
|
+
candidateIndex: candIdx,
|
|
668
|
+
candidateKeys: Object.keys(candidate),
|
|
669
|
+
candidate: JSON.stringify(candidate).substring(0, 200)
|
|
670
|
+
});
|
|
576
671
|
}
|
|
577
672
|
}
|
|
578
673
|
} else {
|
|
@@ -592,13 +687,19 @@ function parseGeminiResponse(response, logger) {
|
|
|
592
687
|
});
|
|
593
688
|
}
|
|
594
689
|
}
|
|
690
|
+
logger?.debug("parseGeminiResponse 完成", {
|
|
691
|
+
extractedImagesCount: images.length,
|
|
692
|
+
hasCandidates: !!response.candidates,
|
|
693
|
+
candidatesCount: response.candidates?.length || 0
|
|
694
|
+
});
|
|
595
695
|
if (images.length === 0) {
|
|
596
696
|
logger?.error("未能从 Gemini API 响应中提取到任何图片", {
|
|
597
697
|
hasCandidates: !!response.candidates,
|
|
598
698
|
candidatesCount: response.candidates?.length || 0,
|
|
599
699
|
responseKeys: Object.keys(response),
|
|
600
|
-
firstCandidate: response.candidates?.[0] ? JSON.stringify(response.candidates[0]).substring(0,
|
|
601
|
-
promptFeedback: response.promptFeedback ? JSON.stringify(response.promptFeedback) : null
|
|
700
|
+
firstCandidate: response.candidates?.[0] ? JSON.stringify(response.candidates[0]).substring(0, 500) : null,
|
|
701
|
+
promptFeedback: response.promptFeedback ? JSON.stringify(response.promptFeedback) : null,
|
|
702
|
+
fullResponse: JSON.stringify(response).substring(0, 1e3)
|
|
602
703
|
});
|
|
603
704
|
}
|
|
604
705
|
return images;
|
|
@@ -693,18 +794,60 @@ var GeminiProvider = class {
|
|
|
693
794
|
});
|
|
694
795
|
} else {
|
|
695
796
|
logger.success("Gemini API 调用成功", { current: i + 1, total: numImages, imagesCount: images.length });
|
|
797
|
+
logger.debug("开始流式处理图片", {
|
|
798
|
+
imagesCount: images.length,
|
|
799
|
+
hasCallback: !!onImageGenerated,
|
|
800
|
+
current: i + 1,
|
|
801
|
+
total: numImages
|
|
802
|
+
});
|
|
696
803
|
for (let imgIdx = 0; imgIdx < images.length; imgIdx++) {
|
|
697
804
|
const imageUrl = images[imgIdx];
|
|
698
805
|
const currentIndex = allImages.length;
|
|
699
806
|
allImages.push(imageUrl);
|
|
807
|
+
logger.debug("准备处理单张图片", {
|
|
808
|
+
imgIdx,
|
|
809
|
+
currentIndex,
|
|
810
|
+
total: numImages,
|
|
811
|
+
imageUrlType: typeof imageUrl,
|
|
812
|
+
imageUrlLength: imageUrl?.length || 0,
|
|
813
|
+
imageUrlPrefix: imageUrl?.substring(0, 50) || "null"
|
|
814
|
+
});
|
|
700
815
|
if (onImageGenerated) {
|
|
816
|
+
logger.info("准备调用图片生成回调函数", {
|
|
817
|
+
hasCallback: true,
|
|
818
|
+
currentIndex,
|
|
819
|
+
total: numImages,
|
|
820
|
+
imageUrlLength: imageUrl?.length || 0
|
|
821
|
+
});
|
|
701
822
|
try {
|
|
702
823
|
await onImageGenerated(imageUrl, currentIndex, numImages);
|
|
824
|
+
logger.info("图片生成回调函数执行成功", {
|
|
825
|
+
currentIndex,
|
|
826
|
+
total: numImages,
|
|
827
|
+
imageUrlLength: imageUrl?.length || 0
|
|
828
|
+
});
|
|
703
829
|
} catch (callbackError) {
|
|
704
|
-
logger.
|
|
830
|
+
logger.error("图片生成回调函数执行失败", {
|
|
831
|
+
error: sanitizeError(callbackError),
|
|
832
|
+
errorMessage: callbackError?.message,
|
|
833
|
+
errorStack: callbackError?.stack,
|
|
834
|
+
currentIndex,
|
|
835
|
+
total: numImages,
|
|
836
|
+
imageUrlLength: imageUrl?.length || 0
|
|
837
|
+
});
|
|
705
838
|
}
|
|
839
|
+
} else {
|
|
840
|
+
logger.warn("图片生成回调函数未提供,跳过流式发送", {
|
|
841
|
+
currentIndex,
|
|
842
|
+
total: numImages,
|
|
843
|
+
imageUrlLength: imageUrl?.length || 0
|
|
844
|
+
});
|
|
706
845
|
}
|
|
707
846
|
}
|
|
847
|
+
logger.debug("流式处理图片完成", {
|
|
848
|
+
processedCount: images.length,
|
|
849
|
+
allImagesCount: allImages.length
|
|
850
|
+
});
|
|
708
851
|
}
|
|
709
852
|
} catch (error) {
|
|
710
853
|
const sanitizedError = sanitizeError(error);
|
|
@@ -1395,7 +1538,7 @@ function apply(ctx, config) {
|
|
|
1395
1538
|
充值剩余:${userData.remainingPurchasedCount}次`;
|
|
1396
1539
|
}
|
|
1397
1540
|
__name(buildStatsMessage, "buildStatsMessage");
|
|
1398
|
-
async function recordUserUsage(session, commandName, numImages = 1) {
|
|
1541
|
+
async function recordUserUsage(session, commandName, numImages = 1, sendStatsImmediately = true) {
|
|
1399
1542
|
const userId = session.userId;
|
|
1400
1543
|
const userName = session.username || session.userId || "未知用户";
|
|
1401
1544
|
if (!userId) return;
|
|
@@ -1413,11 +1556,23 @@ function apply(ctx, config) {
|
|
|
1413
1556
|
remainingPurchasedCount: userData.remainingPurchasedCount,
|
|
1414
1557
|
isAdmin: userManager.isAdmin(userId, config)
|
|
1415
1558
|
});
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1559
|
+
if (sendStatsImmediately) {
|
|
1560
|
+
try {
|
|
1561
|
+
const statsMessage = buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config);
|
|
1562
|
+
await session.send(statsMessage);
|
|
1563
|
+
} catch (error) {
|
|
1564
|
+
logger.warn("发送统计信息失败", { userId, error: sanitizeError(error) });
|
|
1565
|
+
}
|
|
1566
|
+
} else {
|
|
1567
|
+
setImmediate(async () => {
|
|
1568
|
+
try {
|
|
1569
|
+
const statsMessage = buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config);
|
|
1570
|
+
await session.send(statsMessage);
|
|
1571
|
+
logger.debug("统计信息已异步发送", { userId, commandName });
|
|
1572
|
+
} catch (error) {
|
|
1573
|
+
logger.warn("异步发送统计信息失败", { userId, error: sanitizeError(error) });
|
|
1574
|
+
}
|
|
1575
|
+
});
|
|
1421
1576
|
}
|
|
1422
1577
|
}
|
|
1423
1578
|
__name(recordUserUsage, "recordUserUsage");
|
|
@@ -1531,14 +1686,29 @@ function apply(ctx, config) {
|
|
|
1531
1686
|
const providerType = requestContext?.provider || config.provider;
|
|
1532
1687
|
const targetModelId = requestContext?.modelId;
|
|
1533
1688
|
const providerInstance = getProviderInstance(providerType, targetModelId);
|
|
1534
|
-
|
|
1535
|
-
|
|
1689
|
+
logger.info("requestProviderImages 调用", {
|
|
1690
|
+
providerType,
|
|
1691
|
+
modelId: targetModelId || "default",
|
|
1692
|
+
numImages,
|
|
1693
|
+
hasCallback: !!onImageGenerated,
|
|
1694
|
+
promptLength: prompt.length,
|
|
1695
|
+
imageUrlsCount: Array.isArray(imageUrls) ? imageUrls.length : imageUrls ? 1 : 0
|
|
1696
|
+
});
|
|
1697
|
+
try {
|
|
1698
|
+
const result = await providerInstance.generateImages(prompt, imageUrls, numImages, onImageGenerated);
|
|
1699
|
+
logger.info("requestProviderImages 完成", {
|
|
1536
1700
|
providerType,
|
|
1537
|
-
|
|
1538
|
-
numImages
|
|
1701
|
+
resultCount: result.length
|
|
1539
1702
|
});
|
|
1703
|
+
return result;
|
|
1704
|
+
} catch (error) {
|
|
1705
|
+
logger.error("requestProviderImages 失败", {
|
|
1706
|
+
providerType,
|
|
1707
|
+
error: sanitizeError(error),
|
|
1708
|
+
errorMessage: error?.message
|
|
1709
|
+
});
|
|
1710
|
+
throw error;
|
|
1540
1711
|
}
|
|
1541
|
-
return await providerInstance.generateImages(prompt, imageUrls, numImages, onImageGenerated);
|
|
1542
1712
|
}
|
|
1543
1713
|
__name(requestProviderImages, "requestProviderImages");
|
|
1544
1714
|
async function processImageWithTimeout(session, img, prompt, styleName, requestContext, displayInfo, mode = "single") {
|
|
@@ -1637,32 +1807,84 @@ ${infoParts.join("\n")}`;
|
|
|
1637
1807
|
const generatedImages = [];
|
|
1638
1808
|
let creditDeducted = false;
|
|
1639
1809
|
const onImageGenerated = /* @__PURE__ */ __name(async (imageUrl, index, total) => {
|
|
1810
|
+
logger.info("流式回调被调用", {
|
|
1811
|
+
userId,
|
|
1812
|
+
index,
|
|
1813
|
+
total,
|
|
1814
|
+
imageUrlType: typeof imageUrl,
|
|
1815
|
+
imageUrlLength: imageUrl?.length || 0,
|
|
1816
|
+
imageUrlPrefix: imageUrl?.substring(0, 50) || "null",
|
|
1817
|
+
hasImageUrl: !!imageUrl
|
|
1818
|
+
});
|
|
1640
1819
|
if (checkTimeout && checkTimeout()) {
|
|
1820
|
+
logger.error("流式回调:检测到超时", { userId, index, total });
|
|
1641
1821
|
throw new Error("命令执行超时");
|
|
1642
1822
|
}
|
|
1643
1823
|
generatedImages.push(imageUrl);
|
|
1824
|
+
logger.debug("图片已添加到 generatedImages", {
|
|
1825
|
+
userId,
|
|
1826
|
+
currentCount: generatedImages.length,
|
|
1827
|
+
index,
|
|
1828
|
+
total
|
|
1829
|
+
});
|
|
1644
1830
|
if (!creditDeducted && generatedImages.length > 0) {
|
|
1645
1831
|
creditDeducted = true;
|
|
1646
|
-
|
|
1647
|
-
|
|
1832
|
+
logger.info("准备扣除积分", { userId, totalImages: total, currentIndex: index });
|
|
1833
|
+
try {
|
|
1834
|
+
await recordUserUsage(session, styleName, total, false);
|
|
1835
|
+
logger.info("流式处理:第一张图片生成,积分已扣除", {
|
|
1836
|
+
userId,
|
|
1837
|
+
totalImages: total,
|
|
1838
|
+
currentIndex: index
|
|
1839
|
+
});
|
|
1840
|
+
} catch (creditError) {
|
|
1841
|
+
logger.error("扣除积分失败", {
|
|
1842
|
+
userId,
|
|
1843
|
+
error: sanitizeError(creditError),
|
|
1844
|
+
totalImages: total
|
|
1845
|
+
});
|
|
1846
|
+
throw creditError;
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
logger.info("准备发送图片", { userId, index: index + 1, total, imageUrlLength: imageUrl?.length || 0 });
|
|
1850
|
+
try {
|
|
1851
|
+
await session.send(import_koishi2.h.image(imageUrl));
|
|
1852
|
+
logger.info("流式处理:图片已发送", { index: index + 1, total, userId });
|
|
1853
|
+
} catch (sendError) {
|
|
1854
|
+
logger.error("发送图片失败", {
|
|
1648
1855
|
userId,
|
|
1649
|
-
|
|
1650
|
-
|
|
1856
|
+
error: sanitizeError(sendError),
|
|
1857
|
+
errorMessage: sendError?.message,
|
|
1858
|
+
index: index + 1,
|
|
1859
|
+
total
|
|
1651
1860
|
});
|
|
1861
|
+
throw sendError;
|
|
1652
1862
|
}
|
|
1653
|
-
await session.send(import_koishi2.h.image(imageUrl));
|
|
1654
|
-
logger.debug("流式处理:图片已发送", { index: index + 1, total });
|
|
1655
1863
|
if (total > 1 && index < total - 1) {
|
|
1864
|
+
logger.debug("多张图片,添加延时", { index, total });
|
|
1656
1865
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1657
1866
|
}
|
|
1658
1867
|
}, "onImageGenerated");
|
|
1868
|
+
logger.info("准备调用 requestProviderImages,已设置回调函数", {
|
|
1869
|
+
userId,
|
|
1870
|
+
hasCallback: !!onImageGenerated,
|
|
1871
|
+
imageCount,
|
|
1872
|
+
promptLength: finalPrompt.length,
|
|
1873
|
+
imageUrlsCount: Array.isArray(imageUrls) ? imageUrls.length : imageUrls ? 1 : 0
|
|
1874
|
+
});
|
|
1659
1875
|
const images = await requestProviderImages(finalPrompt, imageUrls, imageCount, requestContext, onImageGenerated);
|
|
1876
|
+
logger.info("requestProviderImages 返回", {
|
|
1877
|
+
userId,
|
|
1878
|
+
imagesCount: images.length,
|
|
1879
|
+
generatedImagesCount: generatedImages.length,
|
|
1880
|
+
creditDeducted
|
|
1881
|
+
});
|
|
1660
1882
|
if (checkTimeout && checkTimeout()) throw new Error("命令执行超时");
|
|
1661
1883
|
if (images.length === 0) {
|
|
1662
1884
|
return "图像处理失败:未能生成图片";
|
|
1663
1885
|
}
|
|
1664
1886
|
if (!creditDeducted) {
|
|
1665
|
-
await recordUserUsage(session, styleName, images.length);
|
|
1887
|
+
await recordUserUsage(session, styleName, images.length, false);
|
|
1666
1888
|
logger.warn("流式处理:积分在最后扣除(异常情况)", { userId, imagesCount: images.length });
|
|
1667
1889
|
}
|
|
1668
1890
|
await session.send("图像处理完成!");
|
|
@@ -1819,32 +2041,84 @@ Prompt: ${prompt}`);
|
|
|
1819
2041
|
const generatedImages = [];
|
|
1820
2042
|
let creditDeducted = false;
|
|
1821
2043
|
const onImageGenerated = /* @__PURE__ */ __name(async (imageUrl, index, total) => {
|
|
2044
|
+
logger.info("流式回调被调用 (COMPOSE_IMAGE)", {
|
|
2045
|
+
userId,
|
|
2046
|
+
index,
|
|
2047
|
+
total,
|
|
2048
|
+
imageUrlType: typeof imageUrl,
|
|
2049
|
+
imageUrlLength: imageUrl?.length || 0,
|
|
2050
|
+
imageUrlPrefix: imageUrl?.substring(0, 50) || "null",
|
|
2051
|
+
hasImageUrl: !!imageUrl
|
|
2052
|
+
});
|
|
1822
2053
|
if (isTimeout) {
|
|
2054
|
+
logger.error("流式回调:检测到超时 (COMPOSE_IMAGE)", { userId, index, total });
|
|
1823
2055
|
throw new Error("命令执行超时");
|
|
1824
2056
|
}
|
|
1825
2057
|
generatedImages.push(imageUrl);
|
|
2058
|
+
logger.debug("图片已添加到 generatedImages (COMPOSE_IMAGE)", {
|
|
2059
|
+
userId,
|
|
2060
|
+
currentCount: generatedImages.length,
|
|
2061
|
+
index,
|
|
2062
|
+
total
|
|
2063
|
+
});
|
|
1826
2064
|
if (!creditDeducted && generatedImages.length > 0) {
|
|
1827
2065
|
creditDeducted = true;
|
|
1828
|
-
|
|
1829
|
-
|
|
2066
|
+
logger.info("准备扣除积分 (COMPOSE_IMAGE)", { userId, totalImages: total, currentIndex: index });
|
|
2067
|
+
try {
|
|
2068
|
+
await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE, total, false);
|
|
2069
|
+
logger.info("流式处理:第一张图片生成,积分已扣除 (COMPOSE_IMAGE)", {
|
|
2070
|
+
userId,
|
|
2071
|
+
totalImages: total,
|
|
2072
|
+
currentIndex: index
|
|
2073
|
+
});
|
|
2074
|
+
} catch (creditError) {
|
|
2075
|
+
logger.error("扣除积分失败 (COMPOSE_IMAGE)", {
|
|
2076
|
+
userId,
|
|
2077
|
+
error: sanitizeError(creditError),
|
|
2078
|
+
totalImages: total
|
|
2079
|
+
});
|
|
2080
|
+
throw creditError;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
logger.info("准备发送图片 (COMPOSE_IMAGE)", { userId, index: index + 1, total, imageUrlLength: imageUrl?.length || 0 });
|
|
2084
|
+
try {
|
|
2085
|
+
await session.send(import_koishi2.h.image(imageUrl));
|
|
2086
|
+
logger.info("流式处理:图片已发送 (COMPOSE_IMAGE)", { index: index + 1, total, userId });
|
|
2087
|
+
} catch (sendError) {
|
|
2088
|
+
logger.error("发送图片失败 (COMPOSE_IMAGE)", {
|
|
1830
2089
|
userId,
|
|
1831
|
-
|
|
1832
|
-
|
|
2090
|
+
error: sanitizeError(sendError),
|
|
2091
|
+
errorMessage: sendError?.message,
|
|
2092
|
+
index: index + 1,
|
|
2093
|
+
total
|
|
1833
2094
|
});
|
|
2095
|
+
throw sendError;
|
|
1834
2096
|
}
|
|
1835
|
-
await session.send(import_koishi2.h.image(imageUrl));
|
|
1836
|
-
logger.debug("流式处理:图片已发送", { index: index + 1, total });
|
|
1837
2097
|
if (total > 1 && index < total - 1) {
|
|
2098
|
+
logger.debug("多张图片,添加延时 (COMPOSE_IMAGE)", { index, total });
|
|
1838
2099
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1839
2100
|
}
|
|
1840
2101
|
}, "onImageGenerated");
|
|
2102
|
+
logger.info("准备调用 requestProviderImages (COMPOSE_IMAGE),已设置回调函数", {
|
|
2103
|
+
userId,
|
|
2104
|
+
hasCallback: !!onImageGenerated,
|
|
2105
|
+
imageCount,
|
|
2106
|
+
promptLength: prompt.length,
|
|
2107
|
+
collectedImagesCount: collectedImages.length
|
|
2108
|
+
});
|
|
1841
2109
|
const resultImages = await requestProviderImages(prompt, collectedImages, imageCount, void 0, onImageGenerated);
|
|
2110
|
+
logger.info("requestProviderImages 返回 (COMPOSE_IMAGE)", {
|
|
2111
|
+
userId,
|
|
2112
|
+
imagesCount: resultImages.length,
|
|
2113
|
+
generatedImagesCount: generatedImages.length,
|
|
2114
|
+
creditDeducted
|
|
2115
|
+
});
|
|
1842
2116
|
if (isTimeout) throw new Error("命令执行超时");
|
|
1843
2117
|
if (resultImages.length === 0) {
|
|
1844
2118
|
return "图片合成失败:未能生成图片";
|
|
1845
2119
|
}
|
|
1846
2120
|
if (!creditDeducted) {
|
|
1847
|
-
await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE, resultImages.length);
|
|
2121
|
+
await recordUserUsage(session, COMMANDS.COMPOSE_IMAGE, resultImages.length, false);
|
|
1848
2122
|
logger.warn("流式处理:积分在最后扣除(异常情况)", { userId, imagesCount: resultImages.length });
|
|
1849
2123
|
}
|
|
1850
2124
|
await session.send("图片合成完成!");
|