feat(infra): route Gemini WS through SOCKS5 proxy (WARP)
Some checks are pending
CI / quality (push) Waiting to run

- Add socks-proxy-agent dependency
- Add resolveGeminiProxyAgent() helper reading GEMINI_PROXY_URL env
- Apply agent to T1 and T2 Gemini WS factory defaults
- No proxy when GEMINI_PROXY_URL is unset (local dev unchanged)
- Tests: 311/311 green
This commit is contained in:
Hermann_Kitio 2026-06-30 20:30:15 +03:00
parent 74770b6402
commit 5263372839
7 changed files with 139 additions and 4 deletions

View file

@ -15,6 +15,23 @@
*/
import { WebSocket as NodeWebSocket } from "ws";
import { SocksProxyAgent } from "socks-proxy-agent";
/**
* Résout l'agent proxy SOCKS5 pour les connexions WebSocket vers Gemini Live.
*
* Contexte : l'IP du VPS de production (datacenter) est bloquée par Google.
* Cloudflare WARP tourne en mode proxy sur le VPS (socks5://127.0.0.1:40000) ;
* router UNIQUEMENT le trafic Gemini via ce proxy le débloque, sans affecter
* le reste (Supabase, DeepSeek, clients).
*
* `GEMINI_PROXY_URL` est optionnelle : absente connexion directe (dev local
* intact). Présente (ex: socks5://127.0.0.1:40000) → SocksProxyAgent.
*/
export function resolveGeminiProxyAgent(): SocksProxyAgent | undefined {
const url = process.env.GEMINI_PROXY_URL;
return url ? new SocksProxyAgent(url) : undefined;
}
export const GEMINI_LIVE_URL =
"wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent";
@ -294,9 +311,14 @@ export function openGeminiLiveSession(
});
const url = `${GEMINI_LIVE_URL}?key=${apiKey}`;
const proxyAgent = resolveGeminiProxyAgent();
const factory =
opts.clientFactory ??
((u: string) => new NodeWebSocket(u) as unknown as WebSocketLike);
((u: string) =>
new NodeWebSocket(
u,
proxyAgent ? { agent: proxyAgent } : undefined,
) as unknown as WebSocketLike);
console.log("[T2] Gemini WS URL:", GEMINI_LIVE_URL + "?key=***");
console.log("[T2] Gemini WS model:", GEMINI_LIVE_MODEL);