koishi-plugin-aka-ai-generator 0.5.1 → 0.5.3
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 +60 -10
- package/lib/providers/types.d.ts +4 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -42,10 +42,14 @@ function sanitizeError(error) {
|
|
|
42
42
|
const sanitized = {};
|
|
43
43
|
for (const key in error) {
|
|
44
44
|
const lowerKey = key.toLowerCase();
|
|
45
|
-
if (lowerKey.includes("apikey") || lowerKey.includes("api_key") || lowerKey
|
|
45
|
+
if (lowerKey.includes("apikey") || lowerKey.includes("api_key") || lowerKey === "key" || lowerKey === "authorization" || lowerKey === "token" || lowerKey === "secret" || lowerKey === "password" || lowerKey === "x-goog-api-key") {
|
|
46
46
|
sanitized[key] = "[REDACTED]";
|
|
47
47
|
continue;
|
|
48
48
|
}
|
|
49
|
+
if (lowerKey === "url" && typeof error[key] === "string") {
|
|
50
|
+
sanitized[key] = sanitizeUrl(error[key]);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
49
53
|
sanitized[key] = sanitizeError(error[key]);
|
|
50
54
|
}
|
|
51
55
|
return sanitized;
|
|
@@ -55,9 +59,26 @@ function sanitizeError(error) {
|
|
|
55
59
|
__name(sanitizeError, "sanitizeError");
|
|
56
60
|
function sanitizeString(str) {
|
|
57
61
|
if (typeof str !== "string") return str;
|
|
58
|
-
|
|
62
|
+
let sanitized = str.replace(/[?&]key=[^&\s"']+/gi, "?key=[REDACTED]").replace(/[?&]apikey=[^&\s"']+/gi, "&apikey=[REDACTED]").replace(/[?&]api_key=[^&\s"']+/gi, "&api_key=[REDACTED]");
|
|
63
|
+
sanitized = sanitized.replace(/key["\s:=]+([a-zA-Z0-9_-]{20,})/gi, 'key="[REDACTED]"').replace(/apikey["\s:=]+([a-zA-Z0-9_-]{20,})/gi, 'apikey="[REDACTED]"').replace(/api_key["\s:=]+([a-zA-Z0-9_-]{20,})/gi, 'api_key="[REDACTED]"').replace(/authorization["\s:=]+(Bearer\s+)?([a-zA-Z0-9_-]{20,})/gi, 'authorization="[REDACTED]"').replace(/Bearer\s+([a-zA-Z0-9_-]{20,})/gi, "Bearer [REDACTED]").replace(/x-goog-api-key["\s:]+([a-zA-Z0-9_-]{20,})/gi, "x-goog-api-key: [REDACTED]").replace(/X-Goog-Api-Key["\s:]+([a-zA-Z0-9_-]{20,})/gi, "X-Goog-Api-Key: [REDACTED]");
|
|
64
|
+
return sanitized;
|
|
59
65
|
}
|
|
60
66
|
__name(sanitizeString, "sanitizeString");
|
|
67
|
+
function sanitizeUrl(url) {
|
|
68
|
+
if (typeof url !== "string") return url;
|
|
69
|
+
try {
|
|
70
|
+
const urlObj = new URL(url);
|
|
71
|
+
urlObj.searchParams.delete("key");
|
|
72
|
+
urlObj.searchParams.delete("apikey");
|
|
73
|
+
urlObj.searchParams.delete("api_key");
|
|
74
|
+
urlObj.searchParams.delete("token");
|
|
75
|
+
urlObj.searchParams.delete("secret");
|
|
76
|
+
return urlObj.toString();
|
|
77
|
+
} catch (e) {
|
|
78
|
+
return sanitizeString(url);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
__name(sanitizeUrl, "sanitizeUrl");
|
|
61
82
|
|
|
62
83
|
// src/providers/yunwu.ts
|
|
63
84
|
async function downloadImageAsBase64(ctx, url, timeout, logger) {
|
|
@@ -752,6 +773,9 @@ var GeminiProvider = class {
|
|
|
752
773
|
this.config = config;
|
|
753
774
|
}
|
|
754
775
|
async generateImages(prompt, imageUrls, numImages) {
|
|
776
|
+
if (!this.config.apiKey || !this.config.apiKey.trim()) {
|
|
777
|
+
throw new Error("Gemini API key 未配置或为空");
|
|
778
|
+
}
|
|
755
779
|
let urls = [];
|
|
756
780
|
if (Array.isArray(imageUrls)) {
|
|
757
781
|
urls = imageUrls.filter((url) => url && typeof url === "string" && url.trim());
|
|
@@ -771,8 +795,8 @@ var GeminiProvider = class {
|
|
|
771
795
|
logger
|
|
772
796
|
);
|
|
773
797
|
imageParts.push({
|
|
774
|
-
|
|
775
|
-
|
|
798
|
+
inlineData: {
|
|
799
|
+
mimeType,
|
|
776
800
|
data
|
|
777
801
|
}
|
|
778
802
|
});
|
|
@@ -792,17 +816,30 @@ var GeminiProvider = class {
|
|
|
792
816
|
}
|
|
793
817
|
],
|
|
794
818
|
generationConfig: {
|
|
795
|
-
responseModalities: ["IMAGE"]
|
|
819
|
+
responseModalities: ["IMAGE"],
|
|
820
|
+
imageConfig: {
|
|
821
|
+
aspectRatio: "16:9"
|
|
822
|
+
}
|
|
796
823
|
}
|
|
797
824
|
};
|
|
798
|
-
logger.debug("调用 Gemini API", {
|
|
825
|
+
logger.debug("调用 Gemini API", {
|
|
826
|
+
prompt: prompt.substring(0, 100),
|
|
827
|
+
imageCount: urls.length,
|
|
828
|
+
numImages,
|
|
829
|
+
current: i + 1,
|
|
830
|
+
endpoint,
|
|
831
|
+
hasApiKey: !!this.config.apiKey,
|
|
832
|
+
apiKeyLength: this.config.apiKey?.length || 0,
|
|
833
|
+
modelId: this.config.modelId
|
|
834
|
+
});
|
|
799
835
|
try {
|
|
800
836
|
const response = await ctx.http.post(
|
|
801
837
|
endpoint,
|
|
802
838
|
requestData,
|
|
803
839
|
{
|
|
804
840
|
headers: {
|
|
805
|
-
"Content-Type": "application/json"
|
|
841
|
+
"Content-Type": "application/json",
|
|
842
|
+
"X-Goog-Api-Key": this.config.apiKey
|
|
806
843
|
},
|
|
807
844
|
params: {
|
|
808
845
|
key: this.config.apiKey
|
|
@@ -825,14 +862,27 @@ var GeminiProvider = class {
|
|
|
825
862
|
} catch (error) {
|
|
826
863
|
const sanitizedError = sanitizeError(error);
|
|
827
864
|
const safeMessage = typeof error?.message === "string" ? sanitizeString(error.message) : "未知错误";
|
|
828
|
-
|
|
865
|
+
const errorDetails = {
|
|
829
866
|
message: safeMessage,
|
|
830
867
|
code: error?.code,
|
|
831
868
|
status: error?.response?.status,
|
|
832
|
-
|
|
869
|
+
statusText: error?.response?.statusText,
|
|
833
870
|
current: i + 1,
|
|
834
871
|
total: numImages
|
|
835
|
-
}
|
|
872
|
+
};
|
|
873
|
+
if (error?.response?.data) {
|
|
874
|
+
try {
|
|
875
|
+
const responseStr = JSON.stringify(error.response.data);
|
|
876
|
+
errorDetails.responseData = sanitizeString(responseStr.substring(0, 1e3));
|
|
877
|
+
} catch (e) {
|
|
878
|
+
errorDetails.responseData = "无法序列化响应数据";
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
if (error?.config) {
|
|
882
|
+
errorDetails.url = error.config.url ? sanitizeUrl(error.config.url) : void 0;
|
|
883
|
+
errorDetails.method = error.config.method;
|
|
884
|
+
}
|
|
885
|
+
logger.error("Gemini API 调用失败", errorDetails);
|
|
836
886
|
if (allImages.length > 0) {
|
|
837
887
|
logger.warn("部分图片生成失败,返回已生成的图片", { generated: allImages.length, requested: numImages });
|
|
838
888
|
break;
|
package/lib/providers/types.d.ts
CHANGED