From 26069f5d66585e2e6ff7c1905480b42860f2ffb3 Mon Sep 17 00:00:00 2001 From: Piotr Oleszczyk Date: Sat, 28 Feb 2026 21:57:12 +0100 Subject: [PATCH] fix(backend): increase max_output_tokens to 65536, log finish_reason on error Replace truncation-recovery heuristic with a higher token budget. On JSON parse failure, log finish_reason and 160-char error context to make the root cause visible. Co-Authored-By: Claude Sonnet 4.6 --- backend/innercontext/api/products.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/backend/innercontext/api/products.py b/backend/innercontext/api/products.py index f4834c6..6e237aa 100644 --- a/backend/innercontext/api/products.py +++ b/backend/innercontext/api/products.py @@ -360,13 +360,18 @@ def parse_product_text(data: ProductParseRequest) -> ProductParseResponse: config=genai_types.GenerateContentConfig( system_instruction=_product_parse_system_prompt(), response_mime_type="application/json", - max_output_tokens=8192, + max_output_tokens=65536, temperature=0.0, ), ) + candidate = response.candidates[0] if response.candidates else None + finish_reason = str(candidate.finish_reason) if candidate else "unknown" raw = response.text if not raw: - raise HTTPException(status_code=502, detail="LLM returned an empty response") + raise HTTPException( + status_code=502, + detail=f"LLM returned an empty response (finish_reason={finish_reason})", + ) # Fallback: extract JSON object in case the model adds preamble or markdown fences if not raw.lstrip().startswith("{"): start = raw.find("{") @@ -380,7 +385,12 @@ def parse_product_text(data: ProductParseRequest) -> ProductParseResponse: try: parsed = json.loads(raw) except json.JSONDecodeError as e: - log.error("Gemini parse-text raw response (failed):\n%s", raw) + log.error( + "Gemini parse-text JSON error at pos %d finish_reason=%s context=%r", + e.pos, + finish_reason, + raw[max(0, e.pos - 80) : e.pos + 80], + ) raise HTTPException(status_code=502, detail=f"LLM returned invalid JSON: {e}") try: return ProductParseResponse.model_validate(parsed)