koishi-plugin-aka-ai-generator 0.5.4 → 0.5.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.
- package/lib/index.js +11 -65
- package/lib/providers/types.d.ts +0 -4
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -42,14 +42,10 @@ 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.includes("apikey") || lowerKey === "key" || lowerKey === "authorization" || lowerKey === "token" || lowerKey === "secret" || lowerKey === "password") {
|
|
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
|
-
}
|
|
53
49
|
sanitized[key] = sanitizeError(error[key]);
|
|
54
50
|
}
|
|
55
51
|
return sanitized;
|
|
@@ -59,26 +55,9 @@ function sanitizeError(error) {
|
|
|
59
55
|
__name(sanitizeError, "sanitizeError");
|
|
60
56
|
function sanitizeString(str) {
|
|
61
57
|
if (typeof str !== "string") return str;
|
|
62
|
-
|
|
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;
|
|
58
|
+
return str.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]");
|
|
65
59
|
}
|
|
66
60
|
__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");
|
|
82
61
|
|
|
83
62
|
// src/providers/yunwu.ts
|
|
84
63
|
async function downloadImageAsBase64(ctx, url, timeout, logger) {
|
|
@@ -773,9 +752,6 @@ var GeminiProvider = class {
|
|
|
773
752
|
this.config = config;
|
|
774
753
|
}
|
|
775
754
|
async generateImages(prompt, imageUrls, numImages) {
|
|
776
|
-
if (!this.config.apiKey || !this.config.apiKey.trim()) {
|
|
777
|
-
throw new Error("Gemini API key 未配置或为空");
|
|
778
|
-
}
|
|
779
755
|
let urls = [];
|
|
780
756
|
if (Array.isArray(imageUrls)) {
|
|
781
757
|
urls = imageUrls.filter((url) => url && typeof url === "string" && url.trim());
|
|
@@ -795,8 +771,8 @@ var GeminiProvider = class {
|
|
|
795
771
|
logger
|
|
796
772
|
);
|
|
797
773
|
imageParts.push({
|
|
798
|
-
|
|
799
|
-
mimeType,
|
|
774
|
+
inline_data: {
|
|
775
|
+
mime_type: mimeType,
|
|
800
776
|
data
|
|
801
777
|
}
|
|
802
778
|
});
|
|
@@ -808,6 +784,7 @@ var GeminiProvider = class {
|
|
|
808
784
|
const requestData = {
|
|
809
785
|
contents: [
|
|
810
786
|
{
|
|
787
|
+
role: "user",
|
|
811
788
|
parts: [
|
|
812
789
|
{ text: prompt },
|
|
813
790
|
...imageParts
|
|
@@ -815,22 +792,10 @@ var GeminiProvider = class {
|
|
|
815
792
|
}
|
|
816
793
|
],
|
|
817
794
|
generationConfig: {
|
|
818
|
-
responseModalities: ["IMAGE"]
|
|
819
|
-
imageConfig: {
|
|
820
|
-
aspectRatio: "16:9"
|
|
821
|
-
}
|
|
795
|
+
responseModalities: ["IMAGE"]
|
|
822
796
|
}
|
|
823
797
|
};
|
|
824
|
-
logger.debug("调用 Gemini API", {
|
|
825
|
-
prompt: prompt.substring(0, 100),
|
|
826
|
-
imageCount: urls.length,
|
|
827
|
-
numImages,
|
|
828
|
-
current: i + 1,
|
|
829
|
-
endpoint,
|
|
830
|
-
hasApiKey: !!this.config.apiKey,
|
|
831
|
-
apiKeyLength: this.config.apiKey?.length || 0,
|
|
832
|
-
modelId: this.config.modelId
|
|
833
|
-
});
|
|
798
|
+
logger.debug("调用 Gemini API", { prompt, imageCount: urls.length, numImages, current: i + 1, endpoint });
|
|
834
799
|
try {
|
|
835
800
|
const response = await ctx.http.post(
|
|
836
801
|
endpoint,
|
|
@@ -860,33 +825,14 @@ var GeminiProvider = class {
|
|
|
860
825
|
} catch (error) {
|
|
861
826
|
const sanitizedError = sanitizeError(error);
|
|
862
827
|
const safeMessage = typeof error?.message === "string" ? sanitizeString(error.message) : "未知错误";
|
|
863
|
-
|
|
828
|
+
logger.error("Gemini API 调用失败", {
|
|
864
829
|
message: safeMessage,
|
|
865
830
|
code: error?.code,
|
|
866
831
|
status: error?.response?.status,
|
|
867
|
-
|
|
832
|
+
responseData: error?.response?.data ? sanitizeString(JSON.stringify(error.response.data).substring(0, 500)) : void 0,
|
|
868
833
|
current: i + 1,
|
|
869
|
-
total: numImages
|
|
870
|
-
|
|
871
|
-
};
|
|
872
|
-
if (error?.response?.data) {
|
|
873
|
-
try {
|
|
874
|
-
const responseStr = JSON.stringify(error.response.data);
|
|
875
|
-
errorDetails.responseData = sanitizeString(responseStr.substring(0, 1e3));
|
|
876
|
-
} catch (e) {
|
|
877
|
-
errorDetails.responseData = "无法序列化响应数据";
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
if (error?.config) {
|
|
881
|
-
errorDetails.url = error.config.url ? sanitizeUrl(error.config.url) : void 0;
|
|
882
|
-
errorDetails.method = error.config.method;
|
|
883
|
-
errorDetails.hasData = !!error.config.data;
|
|
884
|
-
}
|
|
885
|
-
if (error?.code === "ECONNREFUSED" || error?.code === "ETIMEDOUT" || error?.code === "ENOTFOUND") {
|
|
886
|
-
errorDetails.networkError = true;
|
|
887
|
-
errorDetails.networkErrorCode = error.code;
|
|
888
|
-
}
|
|
889
|
-
logger.error("Gemini API 调用失败", errorDetails);
|
|
834
|
+
total: numImages
|
|
835
|
+
});
|
|
890
836
|
if (allImages.length > 0) {
|
|
891
837
|
logger.warn("部分图片生成失败,返回已生成的图片", { generated: allImages.length, requested: numImages });
|
|
892
838
|
break;
|
package/lib/providers/types.d.ts
CHANGED