Skip to content

feat(combos): badge combo editor steps whose model left the live catalog - #15923

Merged
diegosouzapw merged 12 commits into
cheaper-inference:release/v3.8.53from
tiagovilasboas:feat/13505-combo-stale-model-badge
Oct 25, 2026
Merged

diegosouzapw merged 12 commits into
cheaper-inference:release/v3.8.53from
tiagovilasboas:feat/13505-combo-stale-model-badge

Conversation

@tiagovilasboas

Copy link
Copy Markdown
Contributor

Summary

  • The combo editor now marks a step with an amber Not in live catalog badge when its model is no longer in the provider's live catalog. This is the editor badge follow-up to feat(combos): flag combo steps pinned to models missing from synced catalog #15800.
  • Data path: GET /api/combos/builder/options (the editor already fetches it when it opens) now also returns staleComboRefs. It is built by a new findAllStaleComboModelRefs(), which runs the existing findStaleComboModelRefs for every provider an explicit combo step pins. The detection and its fail-open rule are unchanged: a provider without an authoritative catalog flags nothing. If the check throws, the route returns an empty list, so the builder never breaks because of it.
  • Staleness depends only on the model, so any explicit model step using a flagged model gets the badge. Combo refs and provider/* wildcard steps never get it.
  • No new route, no DB change, no change to the sync flow.

Related Issues

Validation

  • Change type: UI (plus one additive field on an existing management API)
  • Focused tests and category gates: tests/unit/combo-stale-model-refs-13505.test.ts (6/6), tests/unit/combo-builder-options-route.test.ts, tests/unit/dashboard/combos-client-boundary.test.mjs, the vitest UI test (4/4), and the impacted unit set from the test-impact map (896/896, see Coverage Notes)
  • npm run lint scope: eslint + prettier clean on all touched files. check-api-typecheck OK (within the frozen baseline), and no new type errors in the touched files
  • i18n gates: check-new-key-coverage PASS (66 locales), check-key-completeness OK, check-ui-value-drift PASS, check-ui-keys-coverage --threshold=65 PASS
  • Reconciled with the current active release base (release/v3.8.52 @ f9989a14)
  • Production-code changes include new automated tests in this PR

Tests Added Or Updated

  • tests/unit/combo-stale-model-refs-13505.test.ts: new case. findAllStaleComboModelRefs flags only the stale explicit step: a live step, a provider/* wildcard and another provider's step without a catalog are not flagged. GET /api/combos/builder/options returns the same refs in staleComboRefs.
  • tests/unit/dashboard/StaleModelBadge.test.tsx (new, vitest + Testing Library, same pattern as ComboSortSelect.test.tsx): builds the stale set from the refs, matches string and { providerId, model } steps, ignores combo refs and wildcards, and renders the label and tooltip.

Coverage Notes

  • src/lib/combos/staleModelRefs.ts (findAllStaleComboModelRefs) and src/app/api/combos/builder/options/route.ts are covered by the node test with the real DB, the real getModelInfo and the real route.
  • src/app/(dashboard)/dashboard/combos/StaleModelBadge.tsx is covered by the vitest test. The page.tsx change only wires the state and renders the badge.
  • test:scoped: page.tsx, the new StaleModelBadge.tsx and locale files that no node test reads resolve to __RUN_ALL__ in the impact map, even after rebuilding it. Locally I ran the union the selector maps for the other files plus every tests/unit/*i18n*.test.ts: 896/896 passed. The full suite runs in CI.

Reviewer Notes

  • i18n: the editor convention is a combos.* key in en.json read through getI18nOrFallback. check-new-key-coverage blocks a new key unless every locale has a real translation, and markers no longer pass. So the PR adds one key, combos.builderStaleModel, translated in all 66 locales: one line per locale file, 67 lines in total. That is the whole i18n footprint. The badge text doubles as its tooltip, which keeps it to a single key.
  • LOC: about 186 hand-written lines (code + tests) plus 67 locale lines. The locale change is split into four commits by locale range only because of the GraphQL commit payload limit.
  • check-translation-ratio fails on my and phi on the release base itself, with the same numbers with and without this PR. This PR adds no untranslated values.
  • The auto-prune toggle is the other feat(providers): Auto-validate models against provider live catalog on import to prevent stale model errors #13505 follow-up and comes in a separate, independent PR.

GET /api/combos/builder/options now returns staleComboRefs: combo steps
pinned to a model the provider's live catalog no longer lists, across every
provider an explicit step uses. It reuses findStaleComboModelRefs, so the
fail-open rule for providers without an authoritative catalog is unchanged.
A failed check degrades to an empty list instead of breaking the builder.
The combo editor reads staleComboRefs from the builder options it already
fetches on open and marks matching explicit model steps with an amber
"Not in live catalog" badge. Staleness is a property of the model, so any
step using a flagged model is marked. Combo refs and provider wildcards are
never marked.
Adds combos.builderStaleModel ("Not in live catalog") to en.json and its
translation for the am..gu locales. check-new-key-coverage requires a
new key to be translated in every locale; the change is split by locale range
only to stay under the API payload limit.
Translates combos.builderStaleModel ("Not in live catalog") for the
ha..lv locales.
Translates combos.builderStaleModel ("Not in live catalog") for the
ml..ru locales.
Translates combos.builderStaleModel ("Not in live catalog") for the
si..zh-TW locales.
findAllStaleComboModelRefs collected step providers and deduped refs in one nested loop, which crossed the cognitive-complexity limit. Move provider lookup and collection into helpers so the new code adds no violation.
The step row and the review summary repeated the same five-way ternary for the step kind subtitle. Move it into getComboStepKindLabel so the stale badge wiring keeps combos/page.tsx under its frozen file-size ceiling.
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Hi @tiagovilasboas — closing this pull request to clear the open queue. The branch feat/13505-combo-stale-model-badge is kept, so the commits stay. Comment here if it should be reopened.

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Hi @tiagovilasboas — reopening this pull request. The close was a mistake, and it is back in the merge queue. The branch feat/13505-combo-stale-model-badge was kept.

@diegosouzapw diegosouzapw reopened this Oct 10, 2026
@diegosouzapw diegosouzapw added the deferred-v3.8.53 Feat PRs held for v3.8.53. Keep open. Do not merge into v3.8.52. label Oct 13, 2026
@diegosouzapw diegosouzapw changed the title feat(combos): badge combo editor steps whose model left the live catalog [defer] feat(combos): badge combo editor steps whose model left the live catalog Oct 13, 2026
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.52 to release/v3.8.53 October 19, 2026 13:31
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Re-homed to release/v3.8.53: v3.8.52 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

@diegosouzapw diegosouzapw removed the deferred-v3.8.53 Feat PRs held for v3.8.53. Keep open. Do not merge into v3.8.52. label Oct 20, 2026
@diegosouzapw diegosouzapw changed the title [defer] feat(combos): badge combo editor steps whose model left the live catalog feat(combos): badge combo editor steps whose model left the live catalog Oct 20, 2026
@diegosouzapw
diegosouzapw merged commit aa3ab2b into cheaper-inference:release/v3.8.53 Oct 25, 2026
87 of 161 checks passed
diegosouzapw added a commit that referenced this pull request Oct 27, 2026
…odel-test

Resolve combos/page.tsx imports: keep the base's StaleModelBadge import and the
PR's ComboStepTestButton import. The base (#15923) already ships
getComboStepKindLabel in comboPageHelpers.tsx, so drop the PR's duplicate copy
that git merged in silently; page.tsx keeps using the shared helper.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants