From 67e9f0fd6402066e0cf1d3546d7bcebc2475cf15 Mon Sep 17 00:00:00 2001 From: Replit Agent Date: Fri, 20 Mar 2026 02:43:52 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20lazy=20Gemini=20client=20init=20?= =?UTF-8?q?=E2=80=94=20server=20starts=20without=20GEMINI=20env=20vars?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GoogleGenAI client threw at module load if AI_INTEGRATIONS_GEMINI_BASE_URL was unset, crashing the VPS service. Now uses lazy singleton (throws on first use). Routes return 503 gracefully when Gemini is not configured on the host. --- lib/integrations-gemini-ai/src/client.ts | 43 +++++++++++++------ .../src/image/client.ts | 24 ++--------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/lib/integrations-gemini-ai/src/client.ts b/lib/integrations-gemini-ai/src/client.ts index 2d4be6f..7c76a61 100644 --- a/lib/integrations-gemini-ai/src/client.ts +++ b/lib/integrations-gemini-ai/src/client.ts @@ -1,21 +1,38 @@ import { GoogleGenAI } from "@google/genai"; -if (!process.env.AI_INTEGRATIONS_GEMINI_BASE_URL) { - throw new Error( - "AI_INTEGRATIONS_GEMINI_BASE_URL must be set. Did you forget to provision the Gemini AI integration?", - ); +function createClient(): GoogleGenAI { + if (!process.env.AI_INTEGRATIONS_GEMINI_BASE_URL) { + throw new Error( + "AI_INTEGRATIONS_GEMINI_BASE_URL must be set. Did you forget to provision the Gemini AI integration?", + ); + } + + if (!process.env.AI_INTEGRATIONS_GEMINI_API_KEY) { + throw new Error( + "AI_INTEGRATIONS_GEMINI_API_KEY must be set. Did you forget to provision the Gemini AI integration?", + ); + } + + return new GoogleGenAI({ + apiKey: process.env.AI_INTEGRATIONS_GEMINI_API_KEY, + httpOptions: { + apiVersion: "", + baseUrl: process.env.AI_INTEGRATIONS_GEMINI_BASE_URL, + }, + }); } -if (!process.env.AI_INTEGRATIONS_GEMINI_API_KEY) { - throw new Error( - "AI_INTEGRATIONS_GEMINI_API_KEY must be set. Did you forget to provision the Gemini AI integration?", - ); +let _ai: GoogleGenAI | null = null; + +export function getAi(): GoogleGenAI { + if (!_ai) { + _ai = createClient(); + } + return _ai; } -export const ai = new GoogleGenAI({ - apiKey: process.env.AI_INTEGRATIONS_GEMINI_API_KEY, - httpOptions: { - apiVersion: "", - baseUrl: process.env.AI_INTEGRATIONS_GEMINI_BASE_URL, +export const ai: GoogleGenAI = new Proxy({} as GoogleGenAI, { + get(_target, prop: keyof GoogleGenAI) { + return getAi()[prop]; }, }); diff --git a/lib/integrations-gemini-ai/src/image/client.ts b/lib/integrations-gemini-ai/src/image/client.ts index 2cf58e3..d769b6a 100644 --- a/lib/integrations-gemini-ai/src/image/client.ts +++ b/lib/integrations-gemini-ai/src/image/client.ts @@ -1,28 +1,10 @@ -import { GoogleGenAI, Modality } from "@google/genai"; - -if (!process.env.AI_INTEGRATIONS_GEMINI_BASE_URL) { - throw new Error( - "AI_INTEGRATIONS_GEMINI_BASE_URL must be set. Did you forget to provision the Gemini AI integration?", - ); -} - -if (!process.env.AI_INTEGRATIONS_GEMINI_API_KEY) { - throw new Error( - "AI_INTEGRATIONS_GEMINI_API_KEY must be set. Did you forget to provision the Gemini AI integration?", - ); -} - -export const ai = new GoogleGenAI({ - apiKey: process.env.AI_INTEGRATIONS_GEMINI_API_KEY, - httpOptions: { - apiVersion: "", - baseUrl: process.env.AI_INTEGRATIONS_GEMINI_BASE_URL, - }, -}); +import { Modality } from "@google/genai"; +import { getAi } from "../client.js"; export async function generateImage( prompt: string ): Promise<{ b64_json: string; mimeType: string }> { + const ai = getAi(); const response = await ai.models.generateContent({ model: "gemini-2.5-flash-image", contents: [{ role: "user", parts: [{ text: prompt }] }],