Skip to content

Ladder · Migrate the seven modules that read QVAC_SERVICE_URL directly #160

Description

@lucaosti

Sub-issue of #137. Depends on #151 (inference ladder scaffolding).

Goal

Eliminate the configuration trap where setting QVAC_LOCAL_URL and QVAC_SERVER_URL appears to work but silently has no effect on most of the system.

The problem, verbatim from the code

services/ai/app/core/config.py documents it:

study_service.py, chat_service.py, document_service.py, rag/query_rewriter.py, rag/compressor.py, workers/pipeline.py, and the /health check in main.py each still read QVAC_SERVICE_URL directly rather than through these settings — they will NOT pick up a diverging QVAC_LOCAL_URL/QVAC_SERVER_URL value until migrated onto settings too.

Seven modules bypass the router. Until they are migrated, the inference ladder is decorative: an operator can configure a separate local and server endpoint, see no error, and have most traffic ignore the configuration.

This is the worst kind of bug — it fails silently and looks like success.

Call sites to migrate

  • services/ai/app/services/study_service.py_qvac_client at module level
  • services/ai/app/services/chat_service.py
  • services/ai/app/services/document_service.py
  • services/ai/app/rag/query_rewriter.py
  • services/ai/app/rag/compressor.py
  • services/ai/app/workers/pipeline.py
  • services/ai/app/main.py — the /health check

Tasks

  • Migrate each to resolve its endpoint through settings / qvac_router
  • Tag each call with an appropriate task_type so routing is meaningful
  • Watch for module-level client instantiation: several modules build an httpx.AsyncClient at import time, which captures the URL before configuration can change it. Move to lazy construction where needed
  • Add a startup log line stating the detected tier and the resolved endpoint per task type
  • Remove the stale comment in config.py once complete
  • Grep the codebase to confirm no direct QVAC_SERVICE_URL reads remain outside config.py

Verification

  • Test: set QVAC_LOCAL_URL and QVAC_SERVER_URL to different endpoints and assert each task type reaches the expected one
  • Test: a lint or unit check failing if a module reads QVAC_SERVICE_URL directly, so this cannot regress

Acceptance criteria

  • No module outside config.py reads QVAC_SERVICE_URL directly
  • Diverging local/server URLs demonstrably change routing for every task type
  • Startup logs make the resolved configuration visible
  • A regression guard prevents reintroduction

Why this is the first ladder task

Rungs 0 and 1 are optimisations. This is a correctness fix: without it, the ladder's configuration is a lie.

Metadata

Metadata

Labels

enhancementNew feature or requestmvpRequired for the MVP

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions