fix(gemini): correct fallback model ID + graceful downloads for failed jobs

- gemini-3.1-flash-preview doesn't exist; replace with gemini-3-flash-preview
- GET /jobs/{id}/downloads: return empty {} instead of 400 when job has no
  outputs (e.g. processing_failed before AI stage completes)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-05-08 12:32:39 +01:00
parent 56a3a62368
commit e2391e2603
2 changed files with 10 additions and 9 deletions

View file

@ -1370,20 +1370,21 @@ async def get_job_downloads(
if _ap is not None and not _own and not (_jpid and _jpid in (_ap or [])):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied")
# Allow downloads for jobs that have outputs available
# (PENDING_QC, APPROVED_ENGLISH, TRANSLATING, COMPLETED, etc.)
if job_doc["status"] in [JobStatus.CREATED.value, JobStatus.INGESTING.value, JobStatus.AI_PROCESSING.value]:
# Block only the statuses where outputs can't possibly exist yet
_no_output_statuses = {
JobStatus.CREATED.value,
JobStatus.INGESTING.value,
JobStatus.AI_PROCESSING.value,
}
if job_doc["status"] in _no_output_statuses:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Job is still being processed"
)
# Check if job has outputs
# No outputs yet — return empty instead of 400 (e.g. failed jobs with partial state)
if not job_doc.get("outputs"):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="No outputs available for this job"
)
return JobDownloadsResponse(downloads={})
# Generate signed URLs for all outputs
downloads = {}

View file

@ -45,7 +45,7 @@ async def _record_gemini_usage(
class GeminiService:
_fallback_models: list[str] = [
"gemini-3.1-flash-preview",
"gemini-3-flash-preview",
"gemini-2.5-pro",
]