1import { G as GoogleGenAI } from "./vendor-ai-gQv1oOjO.js"; 2var define_process_env_default = {}; 3class OpenRouterAI { 4 constructor(apiKey) { 5 this.apiKey = apiKey; 6 this.models = { 7 generateContent: async (params) => { 8 var _a, _b, _c, _d; 9 const { model, contents, config } = params; 10 const messages = []; 11 if (config == null ? void 0 : config.systemInstruction) { 12 const sysInst = config.systemInstruction; 13 const parts = sysInst.parts; 14 messages.push({ 15 role: "system", 16 content: typeof sysInst === "string" ? sysInst : ((_a = parts == null ? void 0 : parts[0]) == null ? void 0 : _a.text) || "" 17 }); 18 } 19 let userContent = ""; 20 if (typeof contents === "string") { 21 userContent = contents; 22 } else if (Array.isArray(contents)) { 23 userContent = contents.map((c) => { 24 const parts = c.parts; 25 return (parts == null ? void 0 : parts.map((p) => p.text).join("")) || c.text || ""; 26 }).join("\n"); 27 } else if (contents && typeof contents === "object" && "parts" in contents) { 28 const parts = contents.parts; 29 userContent = parts.map((p) => p.text).join(""); 30 } 31 messages.push({ 32 role: "user", 33 content: userContent 34 }); 35 const body = { 36 model, 37 messages 38 }; 39 if ((config == null ? void 0 : config.temperature) !== void 0) body.temperature = config.temperature; 40 if ((config == null ? void 0 : config.topP) !== void 0) body.top_p = config.topP; 41 if ((config == null ? void 0 : config.topK) !== void 0) body.top_k = config.topK; 42 if ((config == null ? void 0 : config.maxOutputTokens) !== void 0) body.max_tokens = config.maxOutputTokens; 43 if ((config == null ? void 0 : config.responseMimeType) === "application/json") { 44 body.response_format = { type: "json_object" }; 45 } 46 const response = await fetch("https://openrouter.ai/api/v1/chat/completions", { 47 method: "POST", 48 headers: { 49 "Authorization": `Bearer ${this.apiKey}`, 50 "Content-Type": "application/json", 51 "HTTP-Referer": window.location.origin, 52 "X-Title": "Admin Studio" 53 }, 54 body: JSON.stringify(body) 55 }); 56 if (!response.ok) { 57 const errorData = await response.text(); 58 throw new Error(`OpenRouter API Error: ${response.status} - ${errorData}`); 59 } 60 const data = await response.json(); 61 const text = ((_d = (_c = (_b = data.choices) == null ? void 0 : _b[0]) == null ? void 0 : _c.message) == null ? void 0 : _d.content) || ""; 62 return { 63 text, 64 candidates: [{ 65 content: { 66 parts: [{ text }] 67 } 68 }] 69 }; 70 } 71 }; 72 } 73} 74class BackendAIProxy { 75 constructor() { 76 this.models = { 77 generateContent: async (params) => { 78 const response = await fetch("/api/ai/generate", { 79 method: "POST", 80 headers: { "Content-Type": "application/json" }, 81 body: JSON.stringify(params) 82 }); 83 if (!response.ok) { 84 const errorText = await response.text(); 85 throw new Error(errorText); 86 } 87 return response.json(); 88 } 89 }; 90 } 91} 92let aiInstance = null; 93let currentKey = void 0; 94let currentProvider = void 0; 95const getGeminiAI = () => { 96 let apiKey = define_process_env_default.GEMINI_API_KEY || define_process_env_default.API_KEY; 97 if (typeof window !== "undefined") { 98 const localConfig = localStorage.getItem("hamie_ai_config"); 99 if (localConfig) { 100 try { 101 const parsed = JSON.parse(localConfig); 102 if (parsed.apiKey) apiKey = parsed.apiKey; 103 } catch (error) { 104 console.error("Failed to parse AI config for Gemini key:", error); 105 } 106 } 107 } 108 if (apiKey) { 109 return new GoogleGenAI({ apiKey }); 110 } 111 return new BackendAIProxy(); 112}; 113const getAI = () => { 114 let apiKey = define_process_env_default.GEMINI_API_KEY || define_process_env_default.API_KEY; 115 let provider = "gemini"; 116 if (typeof window !== "undefined") { 117 const localConfig = localStorage.getItem("hamie_ai_config"); 118 if (localConfig) {
119 try { 120 const parsed = JSON.parse(localConfig); 121 provider = parsed.provider || "gemini"; 122 if (provider === "openrouter") { 123 if (parsed.openRouterApiKey) apiKey = parsed.openRouterApiKey; 124 } else { 125 if (parsed.apiKey) apiKey = parsed.apiKey; 126 } 127 } catch (error) { 128 console.error("Failed to parse AI config:", error); 129 } 130 } 131 } 132 if (!aiInstance || currentKey !== apiKey || currentProvider !== provider) { 133 currentKey = apiKey; 134 currentProvider = provider; 135 if (!apiKey) { 136 aiInstance = new BackendAIProxy(); 137 } else if (provider === "openrouter") { 138 aiInstance = new OpenRouterAI(apiKey); 139 } else { 140 aiInstance = new GoogleGenAI({ apiKey }); 141 } 142 } 143 return aiInstance; 144}; 145const getAiModel = (defaultModel = "gemini-3-flash-preview") => { 146 if (typeof window !== "undefined") { 147 const localConfig = localStorage.getItem("hamie_ai_config"); 148 if (localConfig) { 149 try { 150 const parsed = JSON.parse(localConfig); 151 if (parsed.provider === "openrouter") { 152 if (parsed.openRouterModel) return parsed.openRouterModel; 153 } else { 154 if (parsed.model) return parsed.model; 155 } 156 } catch (error) { 157 console.error("Failed to parse AI config for model:", error); 158 } 159 } 160 } 161 return defaultModel; 162}; 163const getAiImageModel = (defaultModel = "gemini-2.5-flash-image") => { 164 if (typeof window !== "undefined") { 165 const localConfig = localStorage.getItem("hamie_ai_config"); 166 if (localConfig) { 167 try { 168 const parsed = JSON.parse(localConfig); 169 if (parsed.provider === "openrouter") { 170 if (parsed.openRouterModel) return parsed.openRouterModel; 171 } else { 172 if (parsed.imageModel) return parsed.imageModel; 173 } 174 } catch (error) { 175 console.error("Failed to parse AI config for image model:", error); 176 } 177 } 178 } 179 return defaultModel; 180}; 181const ai = new Proxy({}, { 182 get: (_target, prop) => { 183 const instance = getAI(); 184 return instance[prop]; 185 } 186}); 187export { 188 ai as a, 189 getGeminiAI as b, 190 getAiImageModel as c, 191 getAiModel as g 192};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.