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 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 === "key" || lowerKey === "authorization" || lowerKey === "token" || lowerKey === "secret" || lowerKey === "password" || lowerKey === "x-goog-api-key") {
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
- 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;
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
- inlineData: {
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
- const errorDetails = {
828
+ logger.error("Gemini API 调用失败", {
864
829
  message: safeMessage,
865
830
  code: error?.code,
866
831
  status: error?.response?.status,
867
- statusText: error?.response?.statusText,
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
- errorType: error?.name || error?.constructor?.name || "Unknown"
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;
@@ -22,7 +22,3 @@ 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.4",
4
+ "version": "0.5.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [