diff --git a/server/ai.py b/server/ai.py index 4da193c..6534bb5 100644 --- a/server/ai.py +++ b/server/ai.py @@ -44,6 +44,7 @@ async def _set_cache(db: aiosqlite.Connection, key: str, content: str) -> None: async def _call_openrouter(prompt: str, *, system: str) -> str | None: if not settings.openrouter_api_key: + logger.warning("OPENROUTER_API_KEY not set") return None try: async with httpx.AsyncClient(timeout=30.0) as client: @@ -60,14 +61,31 @@ async def _call_openrouter(prompt: str, *, system: str) -> str | None: {"role": "system", "content": system}, {"role": "user", "content": prompt}, ], - "max_tokens": 120, + "max_tokens": 512, }, ) resp.raise_for_status() data = resp.json() - return data["choices"][0]["message"]["content"].strip() + if data.get("error"): + logger.error("OpenRouter API error (model=%s): %s", settings.openrouter_model, data["error"]) + return None + choices = data.get("choices") or [] + if not choices: + logger.error("OpenRouter returned no choices (model=%s): %s", settings.openrouter_model, data) + return None + message = choices[0].get("message") or {} + content = message.get("content") + if not content or not str(content).strip(): + logger.error( + "OpenRouter empty content (model=%s, finish_reason=%s): %s", + settings.openrouter_model, + choices[0].get("finish_reason"), + data, + ) + return None + return str(content).strip() except Exception: - logger.exception("OpenRouter request failed") + logger.exception("OpenRouter request failed (model=%s)", settings.openrouter_model) return None