koishi-plugin-aka-ai-generator 0.5.2 → 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 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.includes("apikey") || lowerKey === "key" || lowerKey === "authorization" || lowerKey === "token" || lowerKey === "secret" || lowerKey === "password") {
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
- 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]");
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());
@@ -794,12 +818,20 @@ var GeminiProvider = class {
794
818
  generationConfig: {
795
819
  responseModalities: ["IMAGE"],
796
820
  imageConfig: {
797
- aspectRatio: "16:9",
798
- imageSize: "4K"
821
+ aspectRatio: "16:9"
799
822
  }
800
823
  }
801
824
  };
802
- logger.debug("调用 Gemini API", { prompt, imageCount: urls.length, numImages, current: i + 1, endpoint });
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
+ });
803
835
  try {
804
836
  const response = await ctx.http.post(
805
837
  endpoint,
@@ -807,7 +839,10 @@ var GeminiProvider = class {
807
839
  {
808
840
  headers: {
809
841
  "Content-Type": "application/json",
810
- "x-goog-api-key": this.config.apiKey
842
+ "X-Goog-Api-Key": this.config.apiKey
843
+ },
844
+ params: {
845
+ key: this.config.apiKey
811
846
  },
812
847
  timeout: this.config.apiTimeout * 1e3
813
848
  }
@@ -827,14 +862,27 @@ var GeminiProvider = class {
827
862
  } catch (error) {
828
863
  const sanitizedError = sanitizeError(error);
829
864
  const safeMessage = typeof error?.message === "string" ? sanitizeString(error.message) : "未知错误";
830
- logger.error("Gemini API 调用失败", {
865
+ const errorDetails = {
831
866
  message: safeMessage,
832
867
  code: error?.code,
833
868
  status: error?.response?.status,
834
- responseData: error?.response?.data ? sanitizeString(JSON.stringify(error.response.data).substring(0, 500)) : void 0,
869
+ statusText: error?.response?.statusText,
835
870
  current: i + 1,
836
871
  total: numImages
837
- });
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);
838
886
  if (allImages.length > 0) {
839
887
  logger.warn("部分图片生成失败,返回已生成的图片", { generated: allImages.length, requested: numImages });
840
888
  break;
@@ -22,3 +22,7 @@ export declare function sanitizeError(error: any): any;
22
22
  * 清理字符串中的 API KEY 模式
23
23
  */
24
24
  export declare function sanitizeString(str: string): string;
25
+ /**
26
+ * 清理 URL 中的敏感查询参数
27
+ */
28
+ export declare function sanitizeUrl(url: string): string;
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.5.2",
4
+ "version": "0.5.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [