@bonginkan/maria 4.3.8 → 4.3.10

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.
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
+ var secretManager = require('@google-cloud/secret-manager');
4
5
  var fs = require('fs');
5
6
  var path = require('path');
6
7
  var Stream = require('stream');
@@ -19,7 +20,6 @@ var auth = require('firebase-admin/auth');
19
20
  var fsp = require('fs/promises');
20
21
  var crypto = require('crypto');
21
22
  var child_process = require('child_process');
22
- var secretManager = require('@google-cloud/secret-manager');
23
23
  var events = require('events');
24
24
  var generativeAi = require('@google/generative-ai');
25
25
  var OpenAI = require('openai');
@@ -99,6 +99,267 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
99
99
  mod
100
100
  ));
101
101
 
102
+ // src/services/intelligent-model-selector/SecretManagerIntegration.ts
103
+ var SecretManagerIntegration_exports = {};
104
+ __export(SecretManagerIntegration_exports, {
105
+ SecretManagerIntegration: () => SecretManagerIntegration
106
+ });
107
+ var SecretManagerIntegration;
108
+ var init_SecretManagerIntegration = __esm({
109
+ "src/services/intelligent-model-selector/SecretManagerIntegration.ts"() {
110
+ SecretManagerIntegration = class {
111
+ constructor(config) {
112
+ this.config = config;
113
+ this.useGsm = this.shouldUseGsm();
114
+ }
115
+ client = null;
116
+ cache = /* @__PURE__ */ new Map();
117
+ cacheExpiry = /* @__PURE__ */ new Map();
118
+ CACHE_TTL = 36e5;
119
+ // 1 hour
120
+ useGsm;
121
+ MAX_RETRIES = 3;
122
+ BASE_DELAY_MS = 200;
123
+ /** Determine whether GSM should be used in this environment */
124
+ shouldUseGsm() {
125
+ if (process.env.MARIA_DISABLE_GSM === "true") return false;
126
+ if (process.env.GOOGLE_APPLICATION_CREDENTIALS) return true;
127
+ if (process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT) return true;
128
+ if (process.env.CLOUD_RUN_SERVICE || process.env.K_SERVICE) return true;
129
+ if (process.env.GCE_METADATA_HOST) return true;
130
+ return false;
131
+ }
132
+ /** Lazily create Secret Manager client only when permitted */
133
+ ensureClient() {
134
+ if (!this.useGsm) return null;
135
+ if (this.client) return this.client;
136
+ try {
137
+ this.client = new secretManager.SecretManagerServiceClient();
138
+ } catch {
139
+ this.client = null;
140
+ }
141
+ return this.client;
142
+ }
143
+ /**
144
+ * Get API key from Secret Manager with caching
145
+ */
146
+ async getApiKey(provider) {
147
+ const secretName = this.getSecretName(provider);
148
+ if (!secretName) {
149
+ return void 0;
150
+ }
151
+ const client = this.ensureClient();
152
+ if (!client) {
153
+ return this.getFallbackFromEnv(provider);
154
+ }
155
+ const valid = this.getCachedSecret(secretName);
156
+ if (valid) return valid;
157
+ const res = await this.accessWithBackoff(secretName).catch(() => void 0);
158
+ if (res) {
159
+ this.cacheSecret(secretName, res);
160
+ return res;
161
+ }
162
+ const stale = this.cache.get(secretName);
163
+ if (stale) return stale;
164
+ return this.getFallbackFromEnv(provider);
165
+ }
166
+ /**
167
+ * Get all API keys
168
+ */
169
+ async getAllApiKeys() {
170
+ const [googleApiKey, openaiApiKey, anthropicApiKey, groqApiKey] = await Promise.all([
171
+ this.getApiKey("google"),
172
+ this.getApiKey("openai"),
173
+ this.getApiKey("anthropic"),
174
+ this.getApiKey("groq")
175
+ ]);
176
+ return {
177
+ googleApiKey,
178
+ openaiApiKey,
179
+ anthropicApiKey,
180
+ groqApiKey
181
+ };
182
+ }
183
+ /** Fetch optional configuration values (not API keys) */
184
+ async getOptionalConfig() {
185
+ const client = this.ensureClient();
186
+ const read = async (name) => {
187
+ if (!name) return void 0;
188
+ if (!client) return void 0;
189
+ try {
190
+ const resName = `projects/${this.config.projectId}/secrets/${name}/versions/latest`;
191
+ const [version] = await client.accessSecretVersion({ name: resName });
192
+ const payload = version.payload?.data;
193
+ return payload?.toString();
194
+ } catch {
195
+ return void 0;
196
+ }
197
+ };
198
+ const [defaultModel, defaultProvider, lmstudioApiBase, ollamaApiUrl, vllmApiUrl] = await Promise.all([
199
+ read(this.config.secrets.defaultModel || "default-model"),
200
+ read(this.config.secrets.defaultProvider || "default-provider"),
201
+ read(this.config.secrets.lmstudioApiBase || "lmstudio-api-base"),
202
+ read(this.config.secrets.ollamaApiUrl || "ollama-api-url"),
203
+ read(this.config.secrets.vllmApiUrl || "vllm-api-url")
204
+ ]);
205
+ return { defaultModel, defaultProvider, lmstudioApiBase, ollamaApiUrl, vllmApiUrl };
206
+ }
207
+ /**
208
+ * Verify that required secrets exist
209
+ */
210
+ async verifySecrets() {
211
+ const client = this.ensureClient();
212
+ if (!client) {
213
+ return { available: [], missing: [] };
214
+ }
215
+ const available = [];
216
+ const missing = [];
217
+ const providers = ["google", "openai", "anthropic", "groq"];
218
+ for (const provider of providers) {
219
+ const secretName = this.getSecretName(provider);
220
+ if (!secretName) continue;
221
+ try {
222
+ const name = `projects/${this.config.projectId}/secrets/${secretName}`;
223
+ await client.getSecret({ name });
224
+ available.push(provider);
225
+ } catch (error) {
226
+ missing.push(provider);
227
+ }
228
+ }
229
+ return { available, missing };
230
+ }
231
+ /**
232
+ * Create or update a secret
233
+ */
234
+ async createOrUpdateSecret(provider, apiKey) {
235
+ const secretName = this.getSecretName(provider);
236
+ if (!secretName) {
237
+ return false;
238
+ }
239
+ const client = this.ensureClient();
240
+ if (!client) {
241
+ return false;
242
+ }
243
+ const secretId = `projects/${this.config.projectId}/secrets/${secretName}`;
244
+ try {
245
+ let secretExists = false;
246
+ try {
247
+ await client.getSecret({ name: secretId });
248
+ secretExists = true;
249
+ } catch {
250
+ secretExists = false;
251
+ }
252
+ if (!secretExists) {
253
+ await client.createSecret({
254
+ parent: `projects/${this.config.projectId}`,
255
+ secretId: secretName,
256
+ secret: {
257
+ replication: {
258
+ automatic: {}
259
+ },
260
+ labels: {
261
+ service: "ims",
262
+ provider
263
+ }
264
+ }
265
+ });
266
+ }
267
+ await client.addSecretVersion({
268
+ parent: secretId,
269
+ payload: {
270
+ data: Buffer.from(apiKey, "utf8")
271
+ }
272
+ });
273
+ this.cache.delete(secretName);
274
+ this.cacheExpiry.delete(secretName);
275
+ return true;
276
+ } catch (error) {
277
+ return false;
278
+ }
279
+ }
280
+ /**
281
+ * Get secret name for provider
282
+ */
283
+ getSecretName(provider) {
284
+ switch (provider) {
285
+ case "google":
286
+ return this.config.secrets.googleAI || "google-ai-api-key";
287
+ case "openai":
288
+ return this.config.secrets.openAI || "openai-api-key";
289
+ case "anthropic":
290
+ return this.config.secrets.anthropic || "anthropic-api-key";
291
+ case "groq":
292
+ return this.config.secrets.groq || "groq-api-key";
293
+ default:
294
+ return void 0;
295
+ }
296
+ }
297
+ /**
298
+ * Get cached secret if valid
299
+ */
300
+ getCachedSecret(secretName) {
301
+ const expiry = this.cacheExpiry.get(secretName);
302
+ if (!expiry || Date.now() > expiry) {
303
+ this.cache.delete(secretName);
304
+ this.cacheExpiry.delete(secretName);
305
+ return void 0;
306
+ }
307
+ return this.cache.get(secretName);
308
+ }
309
+ /** Access a secret with retry + exponential backoff */
310
+ async accessWithBackoff(secretName) {
311
+ const client = this.ensureClient();
312
+ if (!client) return void 0;
313
+ const name = `projects/${this.config.projectId}/secrets/${secretName}/versions/latest`;
314
+ for (let attempt = 0; attempt < this.MAX_RETRIES; attempt++) {
315
+ try {
316
+ const [version] = await client.accessSecretVersion({ name });
317
+ const payload = version.payload?.data;
318
+ if (!payload) return void 0;
319
+ return payload.toString();
320
+ } catch (e2) {
321
+ if (attempt === this.MAX_RETRIES - 1) break;
322
+ const delay = this.BASE_DELAY_MS * Math.pow(2, attempt);
323
+ await new Promise((r2) => setTimeout(r2, delay));
324
+ }
325
+ }
326
+ return void 0;
327
+ }
328
+ /**
329
+ * Cache a secret
330
+ */
331
+ cacheSecret(secretName, value) {
332
+ this.cache.set(secretName, value);
333
+ this.cacheExpiry.set(secretName, Date.now() + this.CACHE_TTL);
334
+ }
335
+ /**
336
+ * Get fallback from environment variable
337
+ */
338
+ getFallbackFromEnv(provider) {
339
+ switch (provider) {
340
+ case "google":
341
+ return process.env.GOOGLE_AI_API_KEY;
342
+ case "openai":
343
+ return process.env.OPENAI_API_KEY;
344
+ case "anthropic":
345
+ return process.env.ANTHROPIC_API_KEY;
346
+ case "groq":
347
+ return process.env.GROQ_API_KEY;
348
+ default:
349
+ return void 0;
350
+ }
351
+ }
352
+ /**
353
+ * Clear cache
354
+ */
355
+ clearCache() {
356
+ this.cache.clear();
357
+ this.cacheExpiry.clear();
358
+ }
359
+ };
360
+ }
361
+ });
362
+
102
363
  // node_modules/.pnpm/data-uri-to-buffer@4.0.1/node_modules/data-uri-to-buffer/dist/index.js
103
364
  function dataUriToBuffer(uri) {
104
365
  if (!/^data:/i.test(uri)) {
@@ -7035,256 +7296,9 @@ var free_plan_default = {
7035
7296
  ]
7036
7297
  }
7037
7298
  };
7038
- var SecretManagerIntegration = class {
7039
- constructor(config) {
7040
- this.config = config;
7041
- this.useGsm = this.shouldUseGsm();
7042
- }
7043
- client = null;
7044
- cache = /* @__PURE__ */ new Map();
7045
- cacheExpiry = /* @__PURE__ */ new Map();
7046
- CACHE_TTL = 36e5;
7047
- // 1 hour
7048
- useGsm;
7049
- MAX_RETRIES = 3;
7050
- BASE_DELAY_MS = 200;
7051
- /** Determine whether GSM should be used in this environment */
7052
- shouldUseGsm() {
7053
- if (process.env.MARIA_DISABLE_GSM === "true") return false;
7054
- if (process.env.GOOGLE_APPLICATION_CREDENTIALS) return true;
7055
- if (process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT) return true;
7056
- if (process.env.CLOUD_RUN_SERVICE || process.env.K_SERVICE) return true;
7057
- if (process.env.GCE_METADATA_HOST) return true;
7058
- return false;
7059
- }
7060
- /** Lazily create Secret Manager client only when permitted */
7061
- ensureClient() {
7062
- if (!this.useGsm) return null;
7063
- if (this.client) return this.client;
7064
- try {
7065
- this.client = new secretManager.SecretManagerServiceClient();
7066
- } catch {
7067
- this.client = null;
7068
- }
7069
- return this.client;
7070
- }
7071
- /**
7072
- * Get API key from Secret Manager with caching
7073
- */
7074
- async getApiKey(provider) {
7075
- const secretName = this.getSecretName(provider);
7076
- if (!secretName) {
7077
- return void 0;
7078
- }
7079
- const client = this.ensureClient();
7080
- if (!client) {
7081
- return this.getFallbackFromEnv(provider);
7082
- }
7083
- const valid = this.getCachedSecret(secretName);
7084
- if (valid) return valid;
7085
- const res = await this.accessWithBackoff(secretName).catch(() => void 0);
7086
- if (res) {
7087
- this.cacheSecret(secretName, res);
7088
- return res;
7089
- }
7090
- const stale = this.cache.get(secretName);
7091
- if (stale) return stale;
7092
- return this.getFallbackFromEnv(provider);
7093
- }
7094
- /**
7095
- * Get all API keys
7096
- */
7097
- async getAllApiKeys() {
7098
- const [googleApiKey, openaiApiKey, anthropicApiKey, groqApiKey] = await Promise.all([
7099
- this.getApiKey("google"),
7100
- this.getApiKey("openai"),
7101
- this.getApiKey("anthropic"),
7102
- this.getApiKey("groq")
7103
- ]);
7104
- return {
7105
- googleApiKey,
7106
- openaiApiKey,
7107
- anthropicApiKey,
7108
- groqApiKey
7109
- };
7110
- }
7111
- /** Fetch optional configuration values (not API keys) */
7112
- async getOptionalConfig() {
7113
- const client = this.ensureClient();
7114
- const read = async (name) => {
7115
- if (!name) return void 0;
7116
- if (!client) return void 0;
7117
- try {
7118
- const resName = `projects/${this.config.projectId}/secrets/${name}/versions/latest`;
7119
- const [version] = await client.accessSecretVersion({ name: resName });
7120
- const payload = version.payload?.data;
7121
- return payload?.toString();
7122
- } catch {
7123
- return void 0;
7124
- }
7125
- };
7126
- const [defaultModel, defaultProvider, lmstudioApiBase, ollamaApiUrl, vllmApiUrl] = await Promise.all([
7127
- read(this.config.secrets.defaultModel || "default-model"),
7128
- read(this.config.secrets.defaultProvider || "default-provider"),
7129
- read(this.config.secrets.lmstudioApiBase || "lmstudio-api-base"),
7130
- read(this.config.secrets.ollamaApiUrl || "ollama-api-url"),
7131
- read(this.config.secrets.vllmApiUrl || "vllm-api-url")
7132
- ]);
7133
- return { defaultModel, defaultProvider, lmstudioApiBase, ollamaApiUrl, vllmApiUrl };
7134
- }
7135
- /**
7136
- * Verify that required secrets exist
7137
- */
7138
- async verifySecrets() {
7139
- const client = this.ensureClient();
7140
- if (!client) {
7141
- return { available: [], missing: [] };
7142
- }
7143
- const available = [];
7144
- const missing = [];
7145
- const providers = ["google", "openai", "anthropic", "groq"];
7146
- for (const provider of providers) {
7147
- const secretName = this.getSecretName(provider);
7148
- if (!secretName) continue;
7149
- try {
7150
- const name = `projects/${this.config.projectId}/secrets/${secretName}`;
7151
- await client.getSecret({ name });
7152
- available.push(provider);
7153
- } catch (error) {
7154
- missing.push(provider);
7155
- }
7156
- }
7157
- return { available, missing };
7158
- }
7159
- /**
7160
- * Create or update a secret
7161
- */
7162
- async createOrUpdateSecret(provider, apiKey) {
7163
- const secretName = this.getSecretName(provider);
7164
- if (!secretName) {
7165
- return false;
7166
- }
7167
- const client = this.ensureClient();
7168
- if (!client) {
7169
- return false;
7170
- }
7171
- const secretId = `projects/${this.config.projectId}/secrets/${secretName}`;
7172
- try {
7173
- let secretExists = false;
7174
- try {
7175
- await client.getSecret({ name: secretId });
7176
- secretExists = true;
7177
- } catch {
7178
- secretExists = false;
7179
- }
7180
- if (!secretExists) {
7181
- await client.createSecret({
7182
- parent: `projects/${this.config.projectId}`,
7183
- secretId: secretName,
7184
- secret: {
7185
- replication: {
7186
- automatic: {}
7187
- },
7188
- labels: {
7189
- service: "ims",
7190
- provider
7191
- }
7192
- }
7193
- });
7194
- }
7195
- await client.addSecretVersion({
7196
- parent: secretId,
7197
- payload: {
7198
- data: Buffer.from(apiKey, "utf8")
7199
- }
7200
- });
7201
- this.cache.delete(secretName);
7202
- this.cacheExpiry.delete(secretName);
7203
- return true;
7204
- } catch (error) {
7205
- return false;
7206
- }
7207
- }
7208
- /**
7209
- * Get secret name for provider
7210
- */
7211
- getSecretName(provider) {
7212
- switch (provider) {
7213
- case "google":
7214
- return this.config.secrets.googleAI || "google-ai-api-key";
7215
- case "openai":
7216
- return this.config.secrets.openAI || "openai-api-key";
7217
- case "anthropic":
7218
- return this.config.secrets.anthropic || "anthropic-api-key";
7219
- case "groq":
7220
- return this.config.secrets.groq || "groq-api-key";
7221
- default:
7222
- return void 0;
7223
- }
7224
- }
7225
- /**
7226
- * Get cached secret if valid
7227
- */
7228
- getCachedSecret(secretName) {
7229
- const expiry = this.cacheExpiry.get(secretName);
7230
- if (!expiry || Date.now() > expiry) {
7231
- this.cache.delete(secretName);
7232
- this.cacheExpiry.delete(secretName);
7233
- return void 0;
7234
- }
7235
- return this.cache.get(secretName);
7236
- }
7237
- /** Access a secret with retry + exponential backoff */
7238
- async accessWithBackoff(secretName) {
7239
- const client = this.ensureClient();
7240
- if (!client) return void 0;
7241
- const name = `projects/${this.config.projectId}/secrets/${secretName}/versions/latest`;
7242
- for (let attempt = 0; attempt < this.MAX_RETRIES; attempt++) {
7243
- try {
7244
- const [version] = await client.accessSecretVersion({ name });
7245
- const payload = version.payload?.data;
7246
- if (!payload) return void 0;
7247
- return payload.toString();
7248
- } catch (e2) {
7249
- if (attempt === this.MAX_RETRIES - 1) break;
7250
- const delay = this.BASE_DELAY_MS * Math.pow(2, attempt);
7251
- await new Promise((r2) => setTimeout(r2, delay));
7252
- }
7253
- }
7254
- return void 0;
7255
- }
7256
- /**
7257
- * Cache a secret
7258
- */
7259
- cacheSecret(secretName, value) {
7260
- this.cache.set(secretName, value);
7261
- this.cacheExpiry.set(secretName, Date.now() + this.CACHE_TTL);
7262
- }
7263
- /**
7264
- * Get fallback from environment variable
7265
- */
7266
- getFallbackFromEnv(provider) {
7267
- switch (provider) {
7268
- case "google":
7269
- return process.env.GOOGLE_AI_API_KEY;
7270
- case "openai":
7271
- return process.env.OPENAI_API_KEY;
7272
- case "anthropic":
7273
- return process.env.ANTHROPIC_API_KEY;
7274
- case "groq":
7275
- return process.env.GROQ_API_KEY;
7276
- default:
7277
- return void 0;
7278
- }
7279
- }
7280
- /**
7281
- * Clear cache
7282
- */
7283
- clearCache() {
7284
- this.cache.clear();
7285
- this.cacheExpiry.clear();
7286
- }
7287
- };
7299
+
7300
+ // src/services/intelligent-model-selector/IMSFacade.ts
7301
+ init_SecretManagerIntegration();
7288
7302
 
7289
7303
  // src/providers/ai-provider.ts
7290
7304
  var BaseAIProvider = class {
@@ -8532,7 +8546,7 @@ app.get("/health", (req, res) => {
8532
8546
  app.get("/api/status", (req, res) => {
8533
8547
  res.json({
8534
8548
  status: "healthy",
8535
- version: "4.3.8",
8549
+ version: "4.3.10",
8536
8550
  uptime: process.uptime(),
8537
8551
  memory: process.memoryUsage(),
8538
8552
  platform: process.platform,
@@ -8543,7 +8557,7 @@ app.get("/api/status", (req, res) => {
8543
8557
  app.get("/", (req, res) => {
8544
8558
  res.json({
8545
8559
  name: "MARIA CODE API",
8546
- version: "4.3.8",
8560
+ version: "4.3.10",
8547
8561
  status: "running",
8548
8562
  environment: process.env.NODE_ENV || "development",
8549
8563
  endpoints: {
@@ -8652,8 +8666,40 @@ app.post("/api/auth/revoke", async (req, res) => {
8652
8666
  return res.status(500).json({ error: "REVOCATION_FAILED" });
8653
8667
  }
8654
8668
  });
8669
+ var _keysCache = null;
8670
+ async function loadProviderKeys() {
8671
+ if (_keysCache) return _keysCache;
8672
+ try {
8673
+ const { SecretManagerIntegration: SecretManagerIntegration2 } = await Promise.resolve().then(() => (init_SecretManagerIntegration(), SecretManagerIntegration_exports));
8674
+ const sm = new SecretManagerIntegration2({
8675
+ projectId: process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT || "maria-code-470602",
8676
+ secrets: {
8677
+ openAI: "openai-api-key",
8678
+ googleAI: "google-ai-api-key"
8679
+ }
8680
+ });
8681
+ const keys = await sm.getAllApiKeys().catch(() => ({}));
8682
+ _keysCache = {
8683
+ openaiApiKey: keys.openaiApiKey,
8684
+ googleApiKey: keys.googleApiKey
8685
+ };
8686
+ if (_keysCache.googleApiKey && !process.env.GEMINI_API_KEY && !process.env.GOOGLE_API_KEY) {
8687
+ process.env.GEMINI_API_KEY = _keysCache.googleApiKey;
8688
+ }
8689
+ if (_keysCache.openaiApiKey && !process.env.OPENAI_API_KEY) {
8690
+ process.env.OPENAI_API_KEY = _keysCache.openaiApiKey;
8691
+ }
8692
+ } catch {
8693
+ _keysCache = {
8694
+ openaiApiKey: process.env.OPENAI_API_KEY,
8695
+ googleApiKey: process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY
8696
+ };
8697
+ }
8698
+ return _keysCache;
8699
+ }
8655
8700
  app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8656
8701
  try {
8702
+ await loadProviderKeys();
8657
8703
  const auth = req.headers.authorization;
8658
8704
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8659
8705
  const { prompt, model, size = "1024x1024", format = "png", count = 1, seed } = req.body || {};
@@ -8690,6 +8736,7 @@ app.post("/api/v1/image", rateLimitMiddleware, async (req, res) => {
8690
8736
  });
8691
8737
  app.post("/api/v1/video", rateLimitMiddleware, async (req, res) => {
8692
8738
  try {
8739
+ await loadProviderKeys();
8693
8740
  const auth = req.headers.authorization;
8694
8741
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8695
8742
  const { prompt, duration = 5, fps = 24, res: resStr = "1280x720", format = "mp4", model, seed } = req.body || {};
@@ -8794,11 +8841,36 @@ app.post("/v1/ai-proxy", rateLimitMiddleware, async (req, res) => {
8794
8841
  if (!auth || !auth.startsWith("Bearer ")) return res.status(401).json({ error: "unauthorized" });
8795
8842
  const { prompt, taskType } = req.body || {};
8796
8843
  if (!prompt) return res.status(400).json({ error: "bad_request", message: "prompt required" });
8797
- const gemKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
8844
+ const sanitizeKey = (v) => {
8845
+ if (!v) return void 0;
8846
+ let k = String(v).trim();
8847
+ if (!k) return void 0;
8848
+ if (k.startsWith('"') && k.endsWith('"') || k.startsWith("'") && k.endsWith("'")) {
8849
+ k = k.slice(1, -1);
8850
+ }
8851
+ if (/^Bearer\s+/i.test(k)) k = k.replace(/^Bearer\s+/i, "");
8852
+ if (/your_.*key|example|placeholder/i.test(k)) return void 0;
8853
+ if (/\s/.test(k)) k = k.replace(/\s+/g, "");
8854
+ return k || void 0;
8855
+ };
8856
+ const keys = await (async () => {
8857
+ try {
8858
+ return await global.___maria_keys ?? await (async () => {
8859
+ const k = await (await Promise.resolve().then(() => (init_SecretManagerIntegration(), SecretManagerIntegration_exports))).SecretManagerIntegration;
8860
+ const sm = new k({ projectId: process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT || "maria-code-470602", secrets: { openAI: "openai-api-key", googleAI: "google-ai-api-key" } });
8861
+ const all = await sm.getAllApiKeys().catch(() => ({}));
8862
+ global.___maria_keys = all;
8863
+ return all;
8864
+ })();
8865
+ } catch {
8866
+ return {};
8867
+ }
8868
+ })();
8869
+ const gemKey = sanitizeKey(keys?.googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);
8798
8870
  if (gemKey) {
8799
8871
  try {
8800
8872
  const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import('@google/generative-ai');
8801
- const ai = new GoogleGenerativeAI2({ apiKey: gemKey });
8873
+ const ai = new GoogleGenerativeAI2(gemKey);
8802
8874
  const modelName = process.env.MARIA_CODE_MODEL || "gemini-2.5-flash";
8803
8875
  const model2 = ai.getGenerativeModel({ model: modelName });
8804
8876
  const resp = await model2.generateContent({ contents: [{ role: "user", parts: [{ text: prompt }] }] });
@@ -8808,8 +8880,10 @@ app.post("/v1/ai-proxy", rateLimitMiddleware, async (req, res) => {
8808
8880
  console.warn("[AI Proxy] Gemini path failed, falling back to OpenAI:", e2?.message || e2);
8809
8881
  }
8810
8882
  }
8811
- const openaiKey = process.env.OPENAI_API_KEY;
8812
- if (!openaiKey) return res.status(503).json({ error: "provider_unavailable", message: "No provider key (GEMINI_API_KEY/GOOGLE_API_KEY or OPENAI_API_KEY)" });
8883
+ const openaiKey = sanitizeKey(keys?.openaiApiKey || process.env.OPENAI_API_KEY);
8884
+ if (!openaiKey) {
8885
+ return res.status(503).json({ error: "provider_unavailable", message: "No valid provider key (set GEMINI_API_KEY/GOOGLE_API_KEY or OPENAI_API_KEY)" });
8886
+ }
8813
8887
  const OpenAI2 = (await import('openai')).default;
8814
8888
  const client = new OpenAI2({ apiKey: openaiKey });
8815
8889
  let model = process.env.MARIA_CODE_MODEL || "gpt-5-mini";