fix: add rate limit fallback to vision extract endpoint and fix Ask AI button disabled state
Browse files- src/api/v1/chat.py +2 -1
- src/services/gemini_service.py +13 -4
src/api/v1/chat.py
CHANGED
|
@@ -141,7 +141,8 @@ async def chat_stream(request: Request, payload: ChatRequest, uid: str = Depends
|
|
| 141 |
yield "data: [DONE]\n\n"
|
| 142 |
except Exception as e:
|
| 143 |
logger.error(f"Streaming error: {e}")
|
| 144 |
-
|
|
|
|
| 145 |
yield "data: [DONE]\n\n"
|
| 146 |
|
| 147 |
return StreamingResponse(generate(), media_type="text/event-stream")
|
|
|
|
| 141 |
yield "data: [DONE]\n\n"
|
| 142 |
except Exception as e:
|
| 143 |
logger.error(f"Streaming error: {e}")
|
| 144 |
+
err_msg = f"\n\n⚠️ Streaming error: {e}"
|
| 145 |
+
yield f"data: {json.dumps({'content': err_msg, 'type': 'token'})}\n\n"
|
| 146 |
yield "data: [DONE]\n\n"
|
| 147 |
|
| 148 |
return StreamingResponse(generate(), media_type="text/event-stream")
|
src/services/gemini_service.py
CHANGED
|
@@ -246,12 +246,21 @@ class GeminiVisionService:
|
|
| 246 |
try:
|
| 247 |
response = client.models.generate_content(
|
| 248 |
model=self.model_name,
|
| 249 |
-
contents=[
|
| 250 |
-
prompt,
|
| 251 |
-
types.Part.from_bytes(data=image_bytes, mime_type=mime_type)
|
| 252 |
-
],
|
| 253 |
config=config
|
| 254 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
text = response.text.strip() if response.text else ""
|
| 256 |
|
| 257 |
if "EXTRACTED:" in text and "SOLUTION:" in text:
|
|
|
|
| 246 |
try:
|
| 247 |
response = client.models.generate_content(
|
| 248 |
model=self.model_name,
|
| 249 |
+
contents=[prompt, types.Part.from_bytes(data=image_bytes, mime_type=mime_type)],
|
|
|
|
|
|
|
|
|
|
| 250 |
config=config
|
| 251 |
)
|
| 252 |
+
except Exception as e:
|
| 253 |
+
logger.error(f"Primary vision model failed: {e}")
|
| 254 |
+
logger.info("Falling back to gemini-1.5-flash-8b for vision...")
|
| 255 |
+
try:
|
| 256 |
+
response = client.models.generate_content(
|
| 257 |
+
model="gemini-1.5-flash-8b",
|
| 258 |
+
contents=[prompt, types.Part.from_bytes(data=image_bytes, mime_type=mime_type)],
|
| 259 |
+
config=config
|
| 260 |
+
)
|
| 261 |
+
except Exception as e2:
|
| 262 |
+
raise Exception(f"All vision models failed. You might be out of API quota. ({e2})")
|
| 263 |
+
|
| 264 |
text = response.text.strip() if response.text else ""
|
| 265 |
|
| 266 |
if "EXTRACTED:" in text and "SOLUTION:" in text:
|