@bonginkan/maria 4.3.17 → 4.3.19

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.
@@ -8449,34 +8449,55 @@ var IMSFacade = class {
8449
8449
  constructor(options = {}) {
8450
8450
  this.options = options;
8451
8451
  const projectId = options.projectId || process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT || "maria-code-470602";
8452
- this.secrets = new SecretManagerIntegration({ projectId, secrets: {} });
8452
+ this.secrets = new SecretManagerIntegration({
8453
+ projectId,
8454
+ secrets: {
8455
+ openAI: "openai-api-key",
8456
+ googleAI: "google-ai-api-key",
8457
+ anthropic: "anthropic-api-key",
8458
+ groq: "groq-api-key"
8459
+ }
8460
+ });
8453
8461
  }
8454
8462
  secrets;
8455
8463
  /** Route a simple chat request through IMS selection + providers */
8456
8464
  async routeChat(req) {
8457
8465
  const traceId = `ims_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
8458
8466
  const optional = await this.secrets.getOptionalConfig().catch(() => ({}));
8459
- const [openaiApiKey, groqApiKey, anthropicApiKey, googleApiKey] = await Promise.all([
8460
- this.secrets.getApiKey("openai"),
8461
- this.secrets.getApiKey("groq"),
8462
- this.secrets.getApiKey("anthropic"),
8463
- this.secrets.getApiKey("google")
8464
- ]);
8467
+ const allKeys = await this.secrets.getAllApiKeys().catch(() => ({}));
8468
+ const openaiApiKey = allKeys.openaiApiKey || process.env.OPENAI_API_KEY;
8469
+ const groqApiKey = allKeys.groqApiKey || process.env.GROQ_API_KEY;
8470
+ const anthropicApiKey = allKeys.anthropicApiKey || process.env.ANTHROPIC_API_KEY;
8471
+ const googleApiKey = allKeys.googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY;
8465
8472
  const selection = this.selectProviderAndModel({
8466
8473
  defaultProvider: optional.defaultProvider,
8467
8474
  defaultModel: optional.defaultModel,
8468
8475
  keys: { openaiApiKey, groqApiKey, anthropicApiKey, googleApiKey }
8469
8476
  });
8477
+ const anyKey = openaiApiKey || groqApiKey || anthropicApiKey || googleApiKey;
8478
+ if (!anyKey) {
8479
+ const fallback = this.buildPoliteFallback(req.prompt);
8480
+ return {
8481
+ success: true,
8482
+ content: fallback,
8483
+ meta: { provider: "none", model: "none", traceId, reasons: ["no-keys-detected"] }
8484
+ };
8485
+ }
8470
8486
  const adapter = new IMSProviderAdapter({
8471
- openaiApiKey: openaiApiKey || process.env.OPENAI_API_KEY,
8472
- groqApiKey: groqApiKey || process.env.GROQ_API_KEY,
8473
- anthropicApiKey: anthropicApiKey || process.env.ANTHROPIC_API_KEY,
8474
- googleApiKey: googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY,
8487
+ openaiApiKey,
8488
+ groqApiKey,
8489
+ anthropicApiKey,
8490
+ googleApiKey,
8475
8491
  enableMetrics: true,
8476
8492
  enableFallback: true,
8477
8493
  maxRetries: 2
8478
8494
  });
8479
- await adapter.initialize();
8495
+ try {
8496
+ await adapter.initialize();
8497
+ } catch {
8498
+ const fallback = this.buildPoliteFallback(req.prompt);
8499
+ return { success: true, content: fallback, meta: { provider: "none", model: "none", traceId, reasons: ["adapter-init-failed"] } };
8500
+ }
8480
8501
  const modelDef = {
8481
8502
  id: `${selection.provider}:${selection.model}`,
8482
8503
  providerId: selection.provider,
@@ -8499,12 +8520,17 @@ var IMSFacade = class {
8499
8520
  generationParams: gen,
8500
8521
  trace: { traceId, routedAt: (/* @__PURE__ */ new Date()).toISOString(), policyUsed: this.options.defaultPolicyId || "dev", fallbackChain: [] }
8501
8522
  };
8502
- const sys = req.systemPrompt && String(req.systemPrompt).trim() || "You are a concise assistant.";
8523
+ const sys = req.systemPrompt && String(req.systemPrompt).trim() || "You are a concise assistant. Make sure you answer in plain text, as a natural chat.";
8503
8524
  const messages = [
8504
8525
  { role: "system", content: sys },
8505
8526
  { role: "user", content: req.prompt }
8506
8527
  ];
8507
- const { content } = await adapter.executeModelCall(messages, routeResult, modelDef);
8528
+ let content = "";
8529
+ try {
8530
+ ({ content } = await adapter.executeModelCall(messages, routeResult, modelDef));
8531
+ } catch {
8532
+ content = this.buildPoliteFallback(req.prompt);
8533
+ }
8508
8534
  return {
8509
8535
  success: true,
8510
8536
  content,
@@ -8516,6 +8542,12 @@ var IMSFacade = class {
8516
8542
  }
8517
8543
  };
8518
8544
  }
8545
+ buildPoliteFallback(prompt) {
8546
+ const p = (prompt || "").trim();
8547
+ return p ? `Sorry, I can't reach the AI service right now.
8548
+ Your request: "${p}"
8549
+ I can still help summarize, clarify, or suggest next steps. Try again in a moment, or ask me to rephrase.` : "Sorry, I can't reach the AI service right now. Please try again in a moment.";
8550
+ }
8519
8551
  selectProviderAndModel(input) {
8520
8552
  const reasons = [];
8521
8553
  if (input.defaultProvider && input.defaultModel) {
@@ -8526,11 +8558,11 @@ var IMSFacade = class {
8526
8558
  }
8527
8559
  reasons.push("override: default-provider has no key");
8528
8560
  }
8529
- if (input.keys.openaiApiKey) return { provider: "openai", model: "gpt-4o", reasons: [...reasons, "fallback: openai key present"] };
8530
- if (input.keys.googleApiKey) return { provider: "google", model: "gemini-2.5-pro", reasons: [...reasons, "fallback: google key present"] };
8561
+ if (input.keys.openaiApiKey) return { provider: "openai", model: "gpt-5-mini", reasons: [...reasons, "fallback: openai key present"] };
8562
+ if (input.keys.googleApiKey) return { provider: "google", model: "gemini-2.5-flash", reasons: [...reasons, "fallback: google key present"] };
8531
8563
  if (input.keys.groqApiKey) return { provider: "groq", model: "llama-3.1-70b-versatile", reasons: [...reasons, "fallback: groq key present"] };
8532
- if (input.keys.anthropicApiKey) return { provider: "anthropic", model: "claude-3-5-sonnet-latest", reasons: [...reasons, "fallback: anthropic key present"] };
8533
- return { provider: "openai", model: "gpt-4o", reasons: [...reasons, "last-resort: no keys detected"] };
8564
+ if (input.keys.anthropicApiKey) return { provider: "anthropic", model: "claude-sonnet-4-20250514", reasons: [...reasons, "fallback: anthropic key present"] };
8565
+ return { provider: "openai", model: "gpt-5-mini", reasons: [...reasons, "last-resort: no keys detected"] };
8534
8566
  }
8535
8567
  hasKey(provider, keys) {
8536
8568
  switch (provider) {
@@ -8589,7 +8621,7 @@ app.get("/api/status", (req, res) => {
8589
8621
  app.get("/", (req, res) => {
8590
8622
  res.json({
8591
8623
  name: "MARIA CODE API",
8592
- version: "4.3.17",
8624
+ version: "4.3.19",
8593
8625
  status: "running",
8594
8626
  environment: process.env.NODE_ENV || "development",
8595
8627
  endpoints: {
@@ -8705,8 +8737,12 @@ app.post("/api/ai", rateLimitMiddleware, async (req, res) => {
8705
8737
  return res.json(resp);
8706
8738
  } catch (error) {
8707
8739
  console.error("[AI API] Error:", error?.message || error);
8708
- const status = error?.status || 500;
8709
- return res.status(status).json({ error: "ai_request_failed", message: error?.message || "AI request failed" });
8740
+ const polite = typeof req.body?.prompt === "string" ? `Sorry, I couldn't reach the AI service right now. Here\u2019s a quick human-style reply to keep you moving:
8741
+
8742
+ ${String(req.body.prompt)}
8743
+
8744
+ If you want, I can try again in a moment or help you rephrase.` : `Sorry, I couldn't reach the AI service right now. Please try again in a moment.`;
8745
+ return res.status(200).json({ success: true, data: { content: polite } });
8710
8746
  }
8711
8747
  });
8712
8748
  app.post("/api/auth/revoke", async (req, res) => {
@@ -8449,34 +8449,55 @@ var IMSFacade = class {
8449
8449
  constructor(options = {}) {
8450
8450
  this.options = options;
8451
8451
  const projectId = options.projectId || process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT || "maria-code-470602";
8452
- this.secrets = new SecretManagerIntegration({ projectId, secrets: {} });
8452
+ this.secrets = new SecretManagerIntegration({
8453
+ projectId,
8454
+ secrets: {
8455
+ openAI: "openai-api-key",
8456
+ googleAI: "google-ai-api-key",
8457
+ anthropic: "anthropic-api-key",
8458
+ groq: "groq-api-key"
8459
+ }
8460
+ });
8453
8461
  }
8454
8462
  secrets;
8455
8463
  /** Route a simple chat request through IMS selection + providers */
8456
8464
  async routeChat(req) {
8457
8465
  const traceId = `ims_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
8458
8466
  const optional = await this.secrets.getOptionalConfig().catch(() => ({}));
8459
- const [openaiApiKey, groqApiKey, anthropicApiKey, googleApiKey] = await Promise.all([
8460
- this.secrets.getApiKey("openai"),
8461
- this.secrets.getApiKey("groq"),
8462
- this.secrets.getApiKey("anthropic"),
8463
- this.secrets.getApiKey("google")
8464
- ]);
8467
+ const allKeys = await this.secrets.getAllApiKeys().catch(() => ({}));
8468
+ const openaiApiKey = allKeys.openaiApiKey || process.env.OPENAI_API_KEY;
8469
+ const groqApiKey = allKeys.groqApiKey || process.env.GROQ_API_KEY;
8470
+ const anthropicApiKey = allKeys.anthropicApiKey || process.env.ANTHROPIC_API_KEY;
8471
+ const googleApiKey = allKeys.googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY;
8465
8472
  const selection = this.selectProviderAndModel({
8466
8473
  defaultProvider: optional.defaultProvider,
8467
8474
  defaultModel: optional.defaultModel,
8468
8475
  keys: { openaiApiKey, groqApiKey, anthropicApiKey, googleApiKey }
8469
8476
  });
8477
+ const anyKey = openaiApiKey || groqApiKey || anthropicApiKey || googleApiKey;
8478
+ if (!anyKey) {
8479
+ const fallback = this.buildPoliteFallback(req.prompt);
8480
+ return {
8481
+ success: true,
8482
+ content: fallback,
8483
+ meta: { provider: "none", model: "none", traceId, reasons: ["no-keys-detected"] }
8484
+ };
8485
+ }
8470
8486
  const adapter = new IMSProviderAdapter({
8471
- openaiApiKey: openaiApiKey || process.env.OPENAI_API_KEY,
8472
- groqApiKey: groqApiKey || process.env.GROQ_API_KEY,
8473
- anthropicApiKey: anthropicApiKey || process.env.ANTHROPIC_API_KEY,
8474
- googleApiKey: googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY,
8487
+ openaiApiKey,
8488
+ groqApiKey,
8489
+ anthropicApiKey,
8490
+ googleApiKey,
8475
8491
  enableMetrics: true,
8476
8492
  enableFallback: true,
8477
8493
  maxRetries: 2
8478
8494
  });
8479
- await adapter.initialize();
8495
+ try {
8496
+ await adapter.initialize();
8497
+ } catch {
8498
+ const fallback = this.buildPoliteFallback(req.prompt);
8499
+ return { success: true, content: fallback, meta: { provider: "none", model: "none", traceId, reasons: ["adapter-init-failed"] } };
8500
+ }
8480
8501
  const modelDef = {
8481
8502
  id: `${selection.provider}:${selection.model}`,
8482
8503
  providerId: selection.provider,
@@ -8499,12 +8520,17 @@ var IMSFacade = class {
8499
8520
  generationParams: gen,
8500
8521
  trace: { traceId, routedAt: (/* @__PURE__ */ new Date()).toISOString(), policyUsed: this.options.defaultPolicyId || "dev", fallbackChain: [] }
8501
8522
  };
8502
- const sys = req.systemPrompt && String(req.systemPrompt).trim() || "You are a concise assistant.";
8523
+ const sys = req.systemPrompt && String(req.systemPrompt).trim() || "You are a concise assistant. Make sure you answer in plain text, as a natural chat.";
8503
8524
  const messages = [
8504
8525
  { role: "system", content: sys },
8505
8526
  { role: "user", content: req.prompt }
8506
8527
  ];
8507
- const { content } = await adapter.executeModelCall(messages, routeResult, modelDef);
8528
+ let content = "";
8529
+ try {
8530
+ ({ content } = await adapter.executeModelCall(messages, routeResult, modelDef));
8531
+ } catch {
8532
+ content = this.buildPoliteFallback(req.prompt);
8533
+ }
8508
8534
  return {
8509
8535
  success: true,
8510
8536
  content,
@@ -8516,6 +8542,12 @@ var IMSFacade = class {
8516
8542
  }
8517
8543
  };
8518
8544
  }
8545
+ buildPoliteFallback(prompt) {
8546
+ const p = (prompt || "").trim();
8547
+ return p ? `Sorry, I can't reach the AI service right now.
8548
+ Your request: "${p}"
8549
+ I can still help summarize, clarify, or suggest next steps. Try again in a moment, or ask me to rephrase.` : "Sorry, I can't reach the AI service right now. Please try again in a moment.";
8550
+ }
8519
8551
  selectProviderAndModel(input) {
8520
8552
  const reasons = [];
8521
8553
  if (input.defaultProvider && input.defaultModel) {
@@ -8526,11 +8558,11 @@ var IMSFacade = class {
8526
8558
  }
8527
8559
  reasons.push("override: default-provider has no key");
8528
8560
  }
8529
- if (input.keys.openaiApiKey) return { provider: "openai", model: "gpt-4o", reasons: [...reasons, "fallback: openai key present"] };
8530
- if (input.keys.googleApiKey) return { provider: "google", model: "gemini-2.5-pro", reasons: [...reasons, "fallback: google key present"] };
8561
+ if (input.keys.openaiApiKey) return { provider: "openai", model: "gpt-5-mini", reasons: [...reasons, "fallback: openai key present"] };
8562
+ if (input.keys.googleApiKey) return { provider: "google", model: "gemini-2.5-flash", reasons: [...reasons, "fallback: google key present"] };
8531
8563
  if (input.keys.groqApiKey) return { provider: "groq", model: "llama-3.1-70b-versatile", reasons: [...reasons, "fallback: groq key present"] };
8532
- if (input.keys.anthropicApiKey) return { provider: "anthropic", model: "claude-3-5-sonnet-latest", reasons: [...reasons, "fallback: anthropic key present"] };
8533
- return { provider: "openai", model: "gpt-4o", reasons: [...reasons, "last-resort: no keys detected"] };
8564
+ if (input.keys.anthropicApiKey) return { provider: "anthropic", model: "claude-sonnet-4-20250514", reasons: [...reasons, "fallback: anthropic key present"] };
8565
+ return { provider: "openai", model: "gpt-5-mini", reasons: [...reasons, "last-resort: no keys detected"] };
8534
8566
  }
8535
8567
  hasKey(provider, keys) {
8536
8568
  switch (provider) {
@@ -8589,7 +8621,7 @@ app.get("/api/status", (req, res) => {
8589
8621
  app.get("/", (req, res) => {
8590
8622
  res.json({
8591
8623
  name: "MARIA CODE API",
8592
- version: "4.3.17",
8624
+ version: "4.3.19",
8593
8625
  status: "running",
8594
8626
  environment: process.env.NODE_ENV || "development",
8595
8627
  endpoints: {
@@ -8705,8 +8737,12 @@ app.post("/api/ai", rateLimitMiddleware, async (req, res) => {
8705
8737
  return res.json(resp);
8706
8738
  } catch (error) {
8707
8739
  console.error("[AI API] Error:", error?.message || error);
8708
- const status = error?.status || 500;
8709
- return res.status(status).json({ error: "ai_request_failed", message: error?.message || "AI request failed" });
8740
+ const polite = typeof req.body?.prompt === "string" ? `Sorry, I couldn't reach the AI service right now. Here\u2019s a quick human-style reply to keep you moving:
8741
+
8742
+ ${String(req.body.prompt)}
8743
+
8744
+ If you want, I can try again in a moment or help you rephrase.` : `Sorry, I couldn't reach the AI service right now. Please try again in a moment.`;
8745
+ return res.status(200).json({ success: true, data: { content: polite } });
8710
8746
  }
8711
8747
  });
8712
8748
  app.post("/api/auth/revoke", async (req, res) => {
@@ -8449,34 +8449,55 @@ var IMSFacade = class {
8449
8449
  constructor(options = {}) {
8450
8450
  this.options = options;
8451
8451
  const projectId = options.projectId || process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT || "maria-code-470602";
8452
- this.secrets = new SecretManagerIntegration({ projectId, secrets: {} });
8452
+ this.secrets = new SecretManagerIntegration({
8453
+ projectId,
8454
+ secrets: {
8455
+ openAI: "openai-api-key",
8456
+ googleAI: "google-ai-api-key",
8457
+ anthropic: "anthropic-api-key",
8458
+ groq: "groq-api-key"
8459
+ }
8460
+ });
8453
8461
  }
8454
8462
  secrets;
8455
8463
  /** Route a simple chat request through IMS selection + providers */
8456
8464
  async routeChat(req) {
8457
8465
  const traceId = `ims_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
8458
8466
  const optional = await this.secrets.getOptionalConfig().catch(() => ({}));
8459
- const [openaiApiKey, groqApiKey, anthropicApiKey, googleApiKey] = await Promise.all([
8460
- this.secrets.getApiKey("openai"),
8461
- this.secrets.getApiKey("groq"),
8462
- this.secrets.getApiKey("anthropic"),
8463
- this.secrets.getApiKey("google")
8464
- ]);
8467
+ const allKeys = await this.secrets.getAllApiKeys().catch(() => ({}));
8468
+ const openaiApiKey = allKeys.openaiApiKey || process.env.OPENAI_API_KEY;
8469
+ const groqApiKey = allKeys.groqApiKey || process.env.GROQ_API_KEY;
8470
+ const anthropicApiKey = allKeys.anthropicApiKey || process.env.ANTHROPIC_API_KEY;
8471
+ const googleApiKey = allKeys.googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY;
8465
8472
  const selection = this.selectProviderAndModel({
8466
8473
  defaultProvider: optional.defaultProvider,
8467
8474
  defaultModel: optional.defaultModel,
8468
8475
  keys: { openaiApiKey, groqApiKey, anthropicApiKey, googleApiKey }
8469
8476
  });
8477
+ const anyKey = openaiApiKey || groqApiKey || anthropicApiKey || googleApiKey;
8478
+ if (!anyKey) {
8479
+ const fallback = this.buildPoliteFallback(req.prompt);
8480
+ return {
8481
+ success: true,
8482
+ content: fallback,
8483
+ meta: { provider: "none", model: "none", traceId, reasons: ["no-keys-detected"] }
8484
+ };
8485
+ }
8470
8486
  const adapter = new IMSProviderAdapter({
8471
- openaiApiKey: openaiApiKey || process.env.OPENAI_API_KEY,
8472
- groqApiKey: groqApiKey || process.env.GROQ_API_KEY,
8473
- anthropicApiKey: anthropicApiKey || process.env.ANTHROPIC_API_KEY,
8474
- googleApiKey: googleApiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.GOOGLE_AI_API_KEY,
8487
+ openaiApiKey,
8488
+ groqApiKey,
8489
+ anthropicApiKey,
8490
+ googleApiKey,
8475
8491
  enableMetrics: true,
8476
8492
  enableFallback: true,
8477
8493
  maxRetries: 2
8478
8494
  });
8479
- await adapter.initialize();
8495
+ try {
8496
+ await adapter.initialize();
8497
+ } catch {
8498
+ const fallback = this.buildPoliteFallback(req.prompt);
8499
+ return { success: true, content: fallback, meta: { provider: "none", model: "none", traceId, reasons: ["adapter-init-failed"] } };
8500
+ }
8480
8501
  const modelDef = {
8481
8502
  id: `${selection.provider}:${selection.model}`,
8482
8503
  providerId: selection.provider,
@@ -8499,12 +8520,17 @@ var IMSFacade = class {
8499
8520
  generationParams: gen,
8500
8521
  trace: { traceId, routedAt: (/* @__PURE__ */ new Date()).toISOString(), policyUsed: this.options.defaultPolicyId || "dev", fallbackChain: [] }
8501
8522
  };
8502
- const sys = req.systemPrompt && String(req.systemPrompt).trim() || "You are a concise assistant.";
8523
+ const sys = req.systemPrompt && String(req.systemPrompt).trim() || "You are a concise assistant. Make sure you answer in plain text, as a natural chat.";
8503
8524
  const messages = [
8504
8525
  { role: "system", content: sys },
8505
8526
  { role: "user", content: req.prompt }
8506
8527
  ];
8507
- const { content } = await adapter.executeModelCall(messages, routeResult, modelDef);
8528
+ let content = "";
8529
+ try {
8530
+ ({ content } = await adapter.executeModelCall(messages, routeResult, modelDef));
8531
+ } catch {
8532
+ content = this.buildPoliteFallback(req.prompt);
8533
+ }
8508
8534
  return {
8509
8535
  success: true,
8510
8536
  content,
@@ -8516,6 +8542,12 @@ var IMSFacade = class {
8516
8542
  }
8517
8543
  };
8518
8544
  }
8545
+ buildPoliteFallback(prompt) {
8546
+ const p = (prompt || "").trim();
8547
+ return p ? `Sorry, I can't reach the AI service right now.
8548
+ Your request: "${p}"
8549
+ I can still help summarize, clarify, or suggest next steps. Try again in a moment, or ask me to rephrase.` : "Sorry, I can't reach the AI service right now. Please try again in a moment.";
8550
+ }
8519
8551
  selectProviderAndModel(input) {
8520
8552
  const reasons = [];
8521
8553
  if (input.defaultProvider && input.defaultModel) {
@@ -8526,11 +8558,11 @@ var IMSFacade = class {
8526
8558
  }
8527
8559
  reasons.push("override: default-provider has no key");
8528
8560
  }
8529
- if (input.keys.openaiApiKey) return { provider: "openai", model: "gpt-4o", reasons: [...reasons, "fallback: openai key present"] };
8530
- if (input.keys.googleApiKey) return { provider: "google", model: "gemini-2.5-pro", reasons: [...reasons, "fallback: google key present"] };
8561
+ if (input.keys.openaiApiKey) return { provider: "openai", model: "gpt-5-mini", reasons: [...reasons, "fallback: openai key present"] };
8562
+ if (input.keys.googleApiKey) return { provider: "google", model: "gemini-2.5-flash", reasons: [...reasons, "fallback: google key present"] };
8531
8563
  if (input.keys.groqApiKey) return { provider: "groq", model: "llama-3.1-70b-versatile", reasons: [...reasons, "fallback: groq key present"] };
8532
- if (input.keys.anthropicApiKey) return { provider: "anthropic", model: "claude-3-5-sonnet-latest", reasons: [...reasons, "fallback: anthropic key present"] };
8533
- return { provider: "openai", model: "gpt-4o", reasons: [...reasons, "last-resort: no keys detected"] };
8564
+ if (input.keys.anthropicApiKey) return { provider: "anthropic", model: "claude-sonnet-4-20250514", reasons: [...reasons, "fallback: anthropic key present"] };
8565
+ return { provider: "openai", model: "gpt-5-mini", reasons: [...reasons, "last-resort: no keys detected"] };
8534
8566
  }
8535
8567
  hasKey(provider, keys) {
8536
8568
  switch (provider) {
@@ -8589,7 +8621,7 @@ app.get("/api/status", (req, res) => {
8589
8621
  app.get("/", (req, res) => {
8590
8622
  res.json({
8591
8623
  name: "MARIA CODE API",
8592
- version: "4.3.17",
8624
+ version: "4.3.19",
8593
8625
  status: "running",
8594
8626
  environment: process.env.NODE_ENV || "development",
8595
8627
  endpoints: {
@@ -8705,8 +8737,12 @@ app.post("/api/ai", rateLimitMiddleware, async (req, res) => {
8705
8737
  return res.json(resp);
8706
8738
  } catch (error) {
8707
8739
  console.error("[AI API] Error:", error?.message || error);
8708
- const status = error?.status || 500;
8709
- return res.status(status).json({ error: "ai_request_failed", message: error?.message || "AI request failed" });
8740
+ const polite = typeof req.body?.prompt === "string" ? `Sorry, I couldn't reach the AI service right now. Here\u2019s a quick human-style reply to keep you moving:
8741
+
8742
+ ${String(req.body.prompt)}
8743
+
8744
+ If you want, I can try again in a moment or help you rephrase.` : `Sorry, I couldn't reach the AI service right now. Please try again in a moment.`;
8745
+ return res.status(200).json({ success: true, data: { content: polite } });
8710
8746
  }
8711
8747
  });
8712
8748
  app.post("/api/auth/revoke", async (req, res) => {