Skip to content

Self-healing catalog reconcile on Refresh (disable retired models) #476

@aaronsb

Description

@aaronsb

Enhancement. A code sketch already exists in `api/app/routes/models.py` (`refresh_catalog`).

Context

`refresh_catalog` upserts the provider's fetched models but never disables catalog rows that are absent from the live fetch. So a retired dated snapshot stays `enabled=TRUE` and `prefer_cheapest`/default resolution can still pick a dead model — exactly how `claude-3-haiku-20240307` (retired 2026-04-19) caused a 404 storm in code-block translation. We patched the seed (migration 059), but the durable fix is reconciliation.

To look into (caveats already noted in the code sketch)

After upsert, disable enabled rows for the provider whose `model_id` is not in the live set, but:

  1. Only when the fetch is known-complete (not paginated/partial) — else valid models get wrongly disabled.
  2. Scope by category (an extraction refresh mustn't disable embedding/vision rows).
  3. Never auto-disable the active extraction model or `is_default` — warn instead.
  4. Distinguish operator-intent disables from auto-disables (a `disabled_reason` column) so a manual enable isn't clobbered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions