Platform, storage, and observability
Routers: llm_provider.py, system.py, oss.py, version.py, observability.py. The root liveness GET /active is registered in app/server/main.py, not under /api.
LLM provider (/api/llm-provider/...)
verifyvsverify-capabilitiesvsverify-multimodalanswer different questions: connectivity, capability probing, and image probes.createreturnsdata: {"provider_id": ...}; use that id inupdateanddelete.- Default providers are protected on delete; see the main doc’s business-error examples.
System and usage stats
GET /api/system/infois used by the SPA to decide registration/login options—do not assume it exposes secret keys.POST /api/system/update_settingsis admin-only.POST /api/system/agent/usage-statsis per-user usage withdaysand optionalagent_id.
Version endpoints (/api/system/version*)
.../checkand.../latestare for different client surfaces (desktop vs web) with different response models.POST/GET/DELETEfor version records are product metadata, not a guarantee of image tags in your cluster.
OSS upload
POST /api/oss/uploadbacks user uploads. Desktop builds may return paths that the UI later maps locally—treat the response schema as part of the contract you test against, not a universal HTTPS URL.
Jaeger and observability
/api/observability/jaeger*routes handle redirects and auth; expect HTML flows for admins and possible503when local login is not available.
Liveness: GET /active vs GET /api/health
/activeis plain text;/api/healthreturns a JSONBaseResponse. Use them for different kinds of checks (LB vs in-app health).
OAuth2 vs /api/auth
- The OAuth2 surface (
/oauth2/*and/api/oauth2/*) is for standards-based clients (metadata,authorize,token,userinfo). Your browser’s username/password form is a different path—see Auth and users and, for a full third-party example, the repo’s OAuth2 Lage integration guide.