feat: translate module — runtime knobs, GRACE anchors, two-layer testing, QA fixes

Implementation:
- Performance knobs: llm_batch_max_rows, llm_concurrency, insert_concurrency,
  multi_lang_mode, batch_aggressiveness, max_in_flight_batches
- Alembic migration f7a8b9c0d1e2 (idempotent, nullable, non-destructive)
- LLM provider capabilities: throughput_class, reasoning_control,
  supports_json_object, default/max_llm_concurrency
- TargetSchemaValidationRequest with conditional validator (sqllab/direct_db)
- Scheduler: background dispatch, local imports for lazy bootstrap

GRACE-Poly compliance:
- Semantic anchors on orchestrator_aggregator, orchestrator_sql, llm_provider
- Shared module _llm_http.py: _apply_reasoning_control extraction (INV_4)
- Alembic migration anchors per C3/C1 template
- Four renamed Svelte components: RunOutcomeSummary, DetectionQualityCard,
  LanguageStatList, SourceLanguageOverride

QA (this session):
- 11 backend test regressions fixed: spec'd MagicMock null fields for new
  columns, _check_translation_cache_bulk retarget, scheduler mock wiring,
  language_detection=auto assertions, token budget constant update
- 4 frontend eslint errors fixed: SvelteSet/SvelteDate imports,
  unused lang parameter, dead isTransientError
- Production bugfix: job_to_response() mapped 6 missing fields
- Pre-existing auth test failure documented (dependencies.py untouched)
- Axiom: 6440 contracts, 0 warnings
This commit is contained in:
2026-07-20 14:19:47 +03:00
parent 31b9a19a0c
commit 49a566359a
80 changed files with 4823 additions and 630 deletions

View File

@@ -981,6 +981,16 @@ async def dataset_websocket_endpoint(websocket: WebSocket, env_id: str):
# @SIDE_EFFECT Queries DB each tick for current run status via TranslationOrchestrator.
# @UX_STATE Streaming -> Terminal (completed/failed/cancelled) -> Close
# @UX_FEEDBACK Client receives {status, total_records, successful_records, failed_records, progressPct, ...}
def _ws_is_client_gone(exc: BaseException) -> bool:
"""True when the peer already closed the socket (do not send again)."""
if isinstance(exc, WebSocketDisconnect):
return True
if isinstance(exc, RuntimeError):
msg = str(exc).lower()
return "close message has been sent" in msg or "not connected" in msg
return False
@app.websocket("/ws/translate/run/{run_id}")
async def translate_run_websocket(websocket: WebSocket, run_id: str):
_set_websocket_trace_id(websocket)
@@ -1011,15 +1021,55 @@ async def translate_run_websocket(websocket: WebSocket, run_id: str):
break
finally:
db.close()
except WebSocketDisconnect:
# Client gone mid-tick — not a status/DB failure; outer handler logs disconnect.
raise
except Exception as tick_err:
logger.explore("Translate run WS tick error", payload={"run_id": run_id}, error=str(tick_err))
await websocket.send_json({"error": str(tick_err)})
err_type = type(tick_err).__name__
err_msg = str(tick_err) or repr(tick_err)
if _ws_is_client_gone(tick_err):
logger.reason(
"Translate run WS client gone during tick",
payload={"run_id": run_id, "error_type": err_type},
error=err_msg,
)
break
logger.explore(
"Translate run WS tick error",
payload={"run_id": run_id, "error_type": err_type},
error=err_msg,
)
try:
await websocket.send_json({"error": err_msg, "error_type": err_type})
except Exception as send_err:
# Peer closed between tick failure and error frame — avoid second failure noise.
logger.reason(
"Translate run WS skip error frame (socket closed)",
payload={
"run_id": run_id,
"error_type": type(send_err).__name__,
},
error=str(send_err) or repr(send_err),
)
break
await asyncio.sleep(1)
except WebSocketDisconnect:
logger.reason("Translate run WS disconnected", payload={"run_id": run_id})
except Exception as exc:
logger.explore("Translate run WS error", payload={"run_id": run_id}, error=str(exc))
err_type = type(exc).__name__
err_msg = str(exc) or repr(exc)
if _ws_is_client_gone(exc):
logger.reason(
"Translate run WS client gone",
payload={"run_id": run_id, "error_type": err_type},
error=err_msg,
)
else:
logger.explore(
"Translate run WS error",
payload={"run_id": run_id, "error_type": err_type},
error=err_msg,
)
logger.reflect("Translate run WS closed", payload={"run_id": run_id})