Model Catalog — Air-Gap Configuration¶
How the model catalog works¶
core-service exposes two APIs for models:
| Endpoint | Access | Returns |
|---|---|---|
GET /api/v1/models |
Super admin only | Full global catalog (all models in ConfigMap) |
GET /api/v1/organization-models |
Org users | Only models enabled for this org |
The UI agent picker calls /api/v1/organization-models — it only shows what has been enabled for
the org, which is a subset of the global catalog.
modelConfig ConfigMap (models.yaml) ← global catalog — all possible models
↓ admin enables via API
organization_models table (DB) ← per-org enabled set
↓ GET /api/v1/organization-models
UI agent picker ← what the user sees
Where the catalog is defined (air-gap)¶
The model catalog is a Kubernetes ConfigMap (core-service-model-config) mounted at
/app/config/models/models.yaml inside the pod. It is generated from the Helm values key
modelConfig.models.
Two layers — last writer wins:
| File | Role |
|---|---|
ask-core-service/helm/values.yaml |
Base catalog (all upstream models — cloud + on-prem) |
mod-ask-devops/applications/core-service/values-mod-auh1-dev-ask.yaml → modelConfig.models |
Air-gap overlay — replaces the base list entirely (Helm list-replace semantics) |
The devops overlay is authoritative for your air-gap environment. Edit the devops overlay, not the chart repo, to add or remove models.
Current air-gap model catalog¶
Location: mod-ask-devops/applications/core-service/values-mod-auh1-dev-ask.yaml → modelConfig.models
modelConfig:
models:
models:
- id: "qwen3-5-122b-a10b"
provider: "Alibaba Cloud"
name: "Qwen3 122B"
version: "3-5"
description: "Open-source reasoning and tool-calling model. 260K context window."
logo_file_name: "qwen.svg"
type: "inference"
supported_languages: [ "English", "Arabic" ]
is_default: true
is_recommended: true
| Model | Foundry served | In catalog | UI visible |
|---|---|---|---|
qwen3-5-122b-a10b |
✅ | ✅ | ✅ (if org-enabled) |
gpt-oss-120b |
✅ | ❌ removed | ❌ |
anthropic/claude-* |
❌ cloud only | ❌ | ❌ |
grok-*, minimax-*, z-ai/* |
❌ cloud only | ❌ | ❌ |
Adding a model to the catalog¶
- Confirm the model is served by Foundry (
curl https://foundry.ask.mod.auh1.dev.dir/model/info) - Add the entry to the devops overlay under
modelConfig.models.models:
- id: "<foundry-model-id>"
provider: "<Provider Name>"
name: "<Display Name>"
version: "<version>"
description: "<short description>"
logo_file_name: "<name>.svg" # must exist in ask-core-service bucket static/logos/llm_models/
type: "inference" # or "embedding"
supported_languages: [ "English" ]
is_default: false
is_recommended: false
- Commit + push → ArgoCD syncs → ConfigMap updates → Reloader restarts core-service pod
- Enable the model for the org via API (see Enabling models for an org)
Removing a model from the catalog¶
Delete the entry from modelConfig.models.models in the devops overlay. After ArgoCD sync:
- The model disappears from
GET /api/v1/models(super admin view) - Any org that had it enabled will still have the DB row but enrichment will return
nullmetadata (the model ID no longer exists in the catalog)
Disable before removing
Before removing from the catalog, disable the model for all orgs via the API. Removing from the catalog while it is still org-enabled causes the org model list to return incomplete records.
Enabling models for an org¶
After adding to the catalog, a super admin must enable the model for each org:
# Get token for org admin
TOKEN=<org-admin-jwt>
ORG_ID=<zitadel-org-id>
curl -sk -X POST \
https://core-service.ask.mod.auh1.dev.dir/api/v1/organization-models/enable \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"org_id\": \"$ORG_ID\",
\"llm_model_id\": [\"qwen3-5-122b-a10b\"],
\"default_model_id\": \"qwen3-5-122b-a10b\"
}"
Check which models are currently enabled for the org:
curl -sk https://core-service.ask.mod.auh1.dev.dir/api/v1/organization-models \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool | grep '"id"'
Disabling a model for an org¶
curl -sk -X DELETE \
https://core-service.ask.mod.auh1.dev.dir/api/v1/organization-models/disable \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"org_id\": \"$ORG_ID\", \"llm_model_id\": \"gpt-oss-120b\"}"
Model logo icons¶
Icons are SVG files served from Ceph S3 (ask-core-service bucket). The logo_file_name field in
the catalog entry must match a file at static/logos/llm_models/<name>.svg.
Currently uploaded:
| File | Models |
|---|---|
qwen.svg |
qwen3-5-122b-a10b, qwen/qwen3-5-122b-a10b, embedding |
openai.svg |
gpt-oss-120b (removed from catalog but icon kept) |
llama.svg |
nvidia/llama-nemotron-rerank-1b-v2 |
falcon.svg |
Falcon models |
claude.svg |
Anthropic models (cloud-only) |
See Ceph S3 Wiring for the full upload procedure.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| Model not in UI picker | Not enabled for the org | POST to /enable endpoint |
| Model in picker but call fails | Model not served by Foundry | Check foundry.ask.mod.auh1.dev.dir/model/info |
| Icon broken (404) | SVG not uploaded to S3 | Upload to ask-core-service bucket at static/logos/llm_models/ |
| Model missing after sync | Removed from devops overlay | Re-add to modelConfig.models.models |
| Org model list returns null metadata | Model removed from catalog while still org-enabled | Re-add to catalog OR disable for that org |