docs(version): clarify APP_VERSION scope + middleware /api prefix rationale

This commit is contained in:
ZdenekSrotyr 2026-05-06 15:29:20 +02:00
parent 57170bc556
commit af2b866961
2 changed files with 19 additions and 7 deletions

View file

@ -185,6 +185,8 @@ def create_app() -> FastAPI:
@app.middleware("http")
async def _add_version_headers(request, call_next):
response = await call_next(request)
# /api/* only — headers are advisory to the agnes CLI; UI/docs/marketplace
# traffic doesn't consume them.
if request.url.path.startswith("/api/"):
response.headers["X-Agnes-Latest-Version"] = APP_VERSION
response.headers["X-Agnes-Min-Version"] = MIN_COMPAT_CLI_VERSION

View file

@ -1,12 +1,22 @@
"""Single source of truth for app + CLI compat versions.
"""Version constants used by FastAPI's `version=` field and the
`X-Agnes-{Latest,Min}-Version` response-header middleware.
`APP_VERSION` is read from package metadata so it tracks `pyproject.toml`
without a manual literal to keep in sync.
`APP_VERSION` reads from package metadata so it tracks `pyproject.toml`
without a manual literal to keep in sync. **This is not a project-wide
single source of truth** `AGNES_VERSION` env var (set by CI/Docker
builds) continues to drive `/api/version`, `/cli/install.sh`, and the
admin UI. Those call sites pre-date `app/version.py` and are out of scope
for this change.
`MIN_COMPAT_CLI_VERSION` is the oldest CLI version the server still accepts
on `/api/*`. Bumped manually when shipping a wire-protocol break. Day-one
value of "0.0.0" means no enforcement set the floor the first time a
deliberate break ships.
`MIN_COMPAT_CLI_VERSION` is the oldest CLI version the server advertises
as compatible on `/api/*` response headers. Enforcement lives in the
client: `cli/client.py:_check_version_headers` exits the CLI when its
local version is below this floor. The middleware itself does not reject
requests older clients just get a header they're free to ignore (in
practice, only the agnes CLI inspects it).
Day-one value of `MIN_COMPAT_CLI_VERSION` is `0.0.0` (no enforcement);
bumped manually when shipping a wire-protocol break.
"""
from importlib.metadata import PackageNotFoundError