VLM router (POST /vlm/analyze):
- Proxies to Spark 2 (Qwen3-VL via vLLM, OpenAI-compatible /v1/chat/completions)
- Port of BTE Svrnty.Bte.Domain/Features/AssetContext/OpenAiVlmClient.cs
+ VlmRubric.cs (rubric prompt builder + score parser)
- Anthropic dialect intentionally dropped — sovereign-only
- New rubric_mode="raw" passes brand_context through verbatim so BTE
ExtractBrandSaga / ImageSetSourceReader (extraction-style prompts that
expect their own JSON schema) get unwrapped JSON back without losing
the score-axis path
FLUX router (POST /flux/render):
- Proxies to Spark 1 (FLUX.2-dev on ComfyUI; /prompt + /history poll + /view)
- Port of SparkBComfyClient.cs + LocalFluxImageProvider.cs + StopgapFluxWorkflow.cs
- Accepts a pre-assembled workflow_json (BTE IRecipeAssembler emits one)
or builds the stopgap FLUX.2 graph from prompt + dims
Tests (pytest):
- test_vlm_parse.py — rubric prompt + score parse, 502 on Spark-down, mocked round-trip
- test_flux_workflow.py — stopgap graph shape, seed variance/determinism, 502 on Spark-down
- test_healthz.py updated (palette/rembg still 4a stubs)
16 pytest tests green.
Smoke (no Spark reachable):
- GET /healthz → 200 {"status":"ok"}
- POST /vlm/analyze → 502 "Spark 2 unreachable" (clear error)
- POST /flux/render → 502 "Spark 1 unreachable" (clear error)
Per BTE refactor audit §3 V — vision capabilities extracted from BTE to the
sovereign vision gateway. Phase 4c (delete-from-BTE) + Phase 4d (HTTP adapter)
follow in BTE.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| src/svrnty_vision | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
svrnty-vision
Sovereign vision HTTP gateway. FastAPI shell that exposes four endpoints:
| Endpoint | Purpose | Implementation |
|---|---|---|
POST /vlm/analyze |
Vision-language model evaluation | Proxies to Spark 2 (Qwen3-VL via vLLM) |
POST /flux/render |
Image generation | Proxies to Spark 1 (FLUX on ComfyUI) |
POST /palette/extract |
Dominant-color palette | In-process (Pillow + colorthief) |
POST /rembg/cutout |
Background removal | In-process (rembg) |
Plus GET /healthz for liveness.
Why it exists
Brand Truth Engine (BTE) is a .NET 10 + Svrnty.CQRS service. Vision tooling (VLM, image gen, palette, rembg) was originally embedded in BTE with cloud provider SDKs (Anthropic, OpenAI, Google, Higgsfield). Per the 2026-05-24 refactor audit, that surface is extracted into this sibling repo so BTE stays narrow and sovereign-first.
Architecture invariant
svrnty-vision is a thin HTTP gateway — it does NOT run heavy ML models in-process. Qwen3-VL runs on Spark 2 (vLLM). FLUX runs on Spark 1 (ComfyUI). svrnty-vision orchestrates HTTP calls to those services and normalises the responses for BTE.
The two in-process exceptions (palette, rembg) are CPU-light Python libraries — Pillow/colorthief and rembg respectively. They land in 4b.
Status
Phase 4a (this commit): scaffold only. All four endpoints return
HTTP 501 Not Implemented. /healthz returns 200.
Phase 4b will port the real logic. Phase 4c deletes the corresponding
.NET code from BTE. Phase 4d wires BTE to call svrnty-vision over HTTP.
See /home/svrnty/workspaces/hermes/sot/01-ROADMAP/BTE-REFACTOR-EXECUTION-PLAN.md.
Run
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e . # required: src/ layout
# either:
python -m svrnty_vision.server
# or:
uvicorn svrnty_vision.server:app --port 8090
curl http://localhost:8090/healthz
# {"status":"ok","version":"0.1.0"}
Test
pytest tests/
Configuration
Copy .env.example to .env and edit. All settings have safe defaults
for local development (Spark 1/2 hostnames are placeholders).