@ikyyofc/gemini-cli 2.0.1 → 2.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikyyofc/gemini-cli",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "AI CLI Agent powered by Gemini — your own terminal assistant",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/gemini.js CHANGED
@@ -1,7 +1,8 @@
1
1
  // src/gemini.js — Gemini API client with native function calling
2
2
  import axios from "axios";
3
3
  import { fileTypeFromBuffer } from "file-type";
4
-
4
+ import { setupGlobalProxy } from '../utils/proxy-manager.js';
5
+ setupGlobalProxy();
5
6
  const CONFIG = {
6
7
  URL: "https://us-central1-gemmy-ai-bdc03.cloudfunctions.net/gemini",
7
8
  MODEL: "gemini-pro-latest",
@@ -0,0 +1,107 @@
1
+ import axios from "axios";
2
+
3
+ // 1. Menghapus data duplikat di proxyPool
4
+ const proxyPool = [
5
+ { name: "caliph", host: "https://cors.caliph.my.id/" },
6
+ { name: "eu", host: "https://cors.eu.org/" },
7
+ { name: "prox", host: "https://prox.26bruunjorl.workers.dev/" },
8
+ { name: "wave", host: "https://plain-wave-6f5f.apis1.workers.dev/" },
9
+ { name: "hill", host: "https://young-hill-815e.apis3.workers.dev/" },
10
+ { name: "icy", host: "https://icy-morning-72e2.apis2.workers.dev/" },
11
+ { name: "fazri", host: "https://cors.fazri.workers.dev/" },
12
+ { name: "spring", host: "https://spring-night-57a1.3540746063.workers.dev/" },
13
+ { name: "sizable", host: "https://cors.sizable.workers.dev/" },
14
+ { name: "jiashu", host: "https://jiashu.1win.eu.org/" },
15
+ { name: "artemisandros", host: "https://cors.artemisandros.workers.dev/?" },
16
+ { name: "supershadowcube", host: "https://cloudflare-cors-anywhere.supershadowcube.workers.dev/?url=" }
17
+ ];
18
+
19
+ const userAgents = [
20
+ // ... (daftar user-agent kamu biarkan sama)
21
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
22
+ ];
23
+
24
+ const failedProxies = new Map();
25
+ const COOLDOWN_TIME = 15 * 60 * 1000;
26
+
27
+ function getRandomProxy() {
28
+ const now = Date.now();
29
+
30
+ for (const [name, failedAt] of failedProxies.entries()) {
31
+ if (now - failedAt > COOLDOWN_TIME) {
32
+ failedProxies.delete(name);
33
+ }
34
+ }
35
+
36
+ const available = proxyPool.filter(p => !failedProxies.has(p.name));
37
+
38
+ if (available.length === 0) {
39
+ failedProxies.clear();
40
+ console.warn("[Global Proxy] ⚠️ Semua proxy gagal, mereset paksa daftar...");
41
+ return proxyPool[Math.floor(Math.random() * proxyPool.length)];
42
+ }
43
+ return available[Math.floor(Math.random() * available.length)];
44
+ }
45
+
46
+ export function setupGlobalProxy() {
47
+ axios.interceptors.request.use(
48
+ config => {
49
+ // Hindari infinite loop pada saat auto-retry
50
+ if (config._isProxied) return config;
51
+
52
+ const url = config.url || "";
53
+ const isInternal = url.includes("localhost") || url.includes("127.0.0.1") || url.startsWith("/");
54
+
55
+ if (isInternal) return config;
56
+
57
+ const alreadyProxied = proxyPool.some(p => url.startsWith(p.host));
58
+ if (alreadyProxied) return config;
59
+
60
+ const proxy = getRandomProxy();
61
+ const randomUA = userAgents[Math.floor(Math.random() * userAgents.length)];
62
+
63
+ // 2. Perbaikan URL Encoding berdasarkan format proxy
64
+ if (proxy.host.endsWith("=") || proxy.host.endsWith("?")) {
65
+ config.url = `${proxy.host}${encodeURIComponent(url)}`;
66
+ } else {
67
+ config.url = `${proxy.host}${url}`;
68
+ }
69
+
70
+ config.proxy = false;
71
+ config.headers = config.headers || {};
72
+
73
+ // Catatan: Ini akan diabaikan oleh browser, tapi berguna di Node.js
74
+ config.headers["User-Agent"] = randomUA;
75
+
76
+ config.metadata = { proxyName: proxy.name, proxyHost: proxy.host, originalUrl: url };
77
+ config._isProxied = true; // Flag untuk retry
78
+
79
+ return config;
80
+ },
81
+ error => Promise.reject(error)
82
+ );
83
+
84
+ axios.interceptors.response.use(
85
+ response => response,
86
+ async error => {
87
+ const config = error.config;
88
+ const meta = config?.metadata;
89
+
90
+ if (meta?.proxyName && !config._retryAttempted) {
91
+ // Tandai proxy gagal
92
+ failedProxies.set(meta.proxyName, Date.now());
93
+ console.warn(`[Global Proxy] ❌ Proxy "${meta.proxyName}" gagal, diblokir sementara.`);
94
+
95
+ // 3. Mekanisme Auto-Retry (Mencoba 1x lagi dengan proxy berbeda)
96
+ config._retryAttempted = true;
97
+ config._isProxied = false; // Reset agar dicegat ulang oleh request interceptor
98
+ config.url = meta.originalUrl; // Kembalikan ke URL asli
99
+
100
+ return axios(config); // Coba request ulang
101
+ }
102
+
103
+ return Promise.reject(error);
104
+ }
105
+ );
106
+
107
+ }