Skip to content

feat(catalog): per-provider retainModels opt-in (#1690, carries #2860) - #3206

Merged
lidge-jun merged 2 commits into
devfrom
codex/retain-models-1690
Sep 1, 2026
Merged

feat(catalog): per-provider retainModels opt-in (#1690, carries #2860)#3206
lidge-jun merged 2 commits into
devfrom
codex/retain-models-1690

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Lands the per-provider retainModels opt-in from [Feature]: config-level retainModels allow-list so operators keep configured models in the authoritative live catalog #1690: ids listed there stay in the routed catalog even when live /models discovery omits them. Carries PR feat(catalog): honor per-provider retainModels opt-in (closes #1690) #2860 (rrmlima, source commit 12e69c200) as the retention predicate (shouldRetainConfiguredProviderModel + modelInList), and takes the config/migration design from PR feat(catalog): config-level retainModels allowlist for authoritative discovery (#1690) #2122 (chilung-cgu) as input.
  • retainModels is self-sufficient: ids no longer need to be repeated in models. The configured seed in fetchProviderModelsWithAuth is now an ordered dedupe union of the Vertex default, models, and retainModels, so a retain-only id survives live discovery, liveModels: false, the degraded fallback, and gets the same context/effort hints as a models entry. selectedModels precedence is unchanged (retain does not imply visible).
  • Opt-in surfaces: zod schema + superRefine validation in src/config.ts (hand-edited "retainModels": "x" fails with a path), management PATCH (null/empty clears, non-blank array validated) and DTO echo, providerManagementConfigError and safe-config key list, and ocx provider edit <name> --retain-models <id,id|-> (- clears).
  • retainModels joins MODEL_ID_LISTS so a retired id is renamed instead of resurrected as a ghost row, and joins the discovery-flight fingerprint.
  • Default behavior is untouched: absent/empty retainModels produces the same catalog as today; the built-in kimi/xai tables still win. Not in this PR: the antigravity gemini-3.7-flash product default, a dashboard field, and the 404-time warning from feat(catalog): config-level retainModels allowlist for authoritative discovery (#1690) #2122.
  • Docs: retainModels row and paragraph in reference/configuration/providers.md (English).

Closes #1690

Verification

  • bun x tsc --noEmit clean.
  • bun run privacy:scan passed.
  • Focused: bun test tests/catalog-retain-models.test.ts tests/model-rename-migration.test.ts tests/cli-headless-parity.test.ts tests/management-provider-validation.test.ts tests/codex-catalog.test.ts → 412 pass / 0 fail. New cases cover the real gatherRoutedModels path (retain-only id survives live omission with hints, single row when live also returns it, liveModels: false, absent list keeps today's drop), config load normalization/rejection, PATCH set/clear round-trip, CLI csv and -, and rename migration.
  • Full suite runs in CI on this PR.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • New Features
    • Added an optional retainModels provider setting to keep specified models visible when live discovery omits them.
    • Added CLI and management API support for setting, viewing, and clearing retained models.
    • Retained models support context and effort metadata, deduplication, and compatibility with disabled live discovery.
  • Bug Fixes
    • Model renames now update retained model entries automatically.
  • Documentation
    • Documented configuration, CLI usage, visibility rules, and upstream compatibility limitations.

rrmlima and others added 2 commits September 2, 2026 03:59
Operators can pin a model id so live discovery keeps it even when the
upstream catalog omits it. The new opt-in is purely additive: built-in
kimi/xai tables and the Vertex default continue to win, unknown ids are
never inflated, and the existing one-line diagnostic still flags ids the
live catalog dropped.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
)

Builds on the carried #2860 predicate. retainModels ids now enter the
configured seed (ordered union with the Vertex default and models), so a
retain-only id survives live discovery, liveModels:false, and gets the same
provider hints; selectedModels precedence is unchanged. Adds zod schema and
superRefine validation, management PATCH/DTO/safe-config plumbing,
ocx provider edit --retain-models <ids|->, rename-migration coverage,
discovery-flight fingerprint, and docs.

Design input: #2122 (union, schema, MODEL_ID_LISTS).
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 1, 2026 19:16
@lidge-jun
lidge-jun merged commit 6a6efa9 into dev Sep 1, 2026
6 of 7 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T19:20:38.683893Z 847571a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@lidge-jun
lidge-jun deleted the codex/retain-models-1690 branch September 1, 2026 19:17
@github-actions github-actions Bot added the enhancement New feature or request label Sep 1, 2026
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: 834f0a90-6a0e-47ae-a79c-d83822a7f8cf

📥 Commits

Reviewing files that changed from the base of the PR and between 53c09a2 and 847571a.

📒 Files selected for processing (14)
  • devlog/_plan/260902_nonbug_adoption_backlog/040_wp4_retain_models.md
  • devlog/_plan/260902_nonbug_adoption_backlog/041_wp4_audit_r1_synthesis.md
  • docs-site/src/content/docs/reference/configuration/providers.md
  • src/cli/provider-runtime.ts
  • src/codex/catalog/provider-fetch.ts
  • src/config.ts
  • src/providers/model-rename-migration.ts
  • src/server/auth-cors.ts
  • src/server/management/provider-routes.ts
  • src/types/provider.ts
  • tests/catalog-retain-models.test.ts
  • tests/cli-headless-parity.test.ts
  • tests/management-provider-validation.test.ts
  • tests/model-rename-migration.test.ts

📝 Walkthrough

Walkthrough

Adds a provider-level retainModels allowlist. Retained model ids remain in routed catalogs when live discovery omits them, including when liveModels is disabled. Configuration, management APIs, CLI editing, migration, documentation, and tests support the field.

Changes

Provider model retention

Layer / File(s) Summary
Configuration and management contracts
src/types/provider.ts, src/config.ts, src/server/auth-cors.ts, src/server/management/provider-routes.ts, tests/management-provider-validation.test.ts
Adds retainModels, validates and normalizes entries, exposes the field through DTOs and provider listings, and supports PATCH persistence and clearing.
Catalog retention and discovery
src/codex/catalog/provider-fetch.ts, tests/catalog-retain-models.test.ts
Includes retained ids in catalog fingerprints and configured seeds. The catalog preserves retained ids through live discovery and liveModels: false, while deduplicating overlaps and applying existing visibility rules.
CLI editing and model migration
src/cli/provider-runtime.ts, src/providers/model-rename-migration.ts, tests/cli-headless-parity.test.ts, tests/model-rename-migration.test.ts
Adds --retain-models, including - clearing semantics, and renames retired ids in retainModels.
Planning and provider documentation
devlog/_plan/260902_nonbug_adoption_backlog/*, docs-site/src/content/docs/reference/configuration/providers.md
Documents the implementation plan, audit decisions, acceptance criteria, exclusions, configuration behavior, and CLI usage.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ProviderRoutes
  participant ProviderConfig
  participant fetchProviderModels
  participant LiveDiscovery
  participant RoutedCatalog
  CLI->>ProviderRoutes: PATCH retainModels list or null
  ProviderRoutes->>ProviderConfig: validate, normalize, and persist
  fetchProviderModels->>LiveDiscovery: request provider models
  LiveDiscovery-->>fetchProviderModels: return live model ids
  fetchProviderModels->>ProviderConfig: read models and retainModels
  fetchProviderModels->>RoutedCatalog: merge retained ids with live models
Loading

Suggested reviewers: ingwannu, luvs01

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/retain-models-1690

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 847571a934

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +399 to +400
if (Object.hasOwn(rawBody, "retainModels")) {
const value = rawBody.retainModels;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve retainModels during provider overwrites

When an operator sets this field with ocx provider edit and later submits the same provider name through the dashboard's Add Provider flow, gui/src/provider-payload.ts omits retainModels and the POST route replaces the entire provider row. Unlike other fields absent from that payload, the overwrite logic does not carry this list forward, so the save silently clears the opt-in and the retained model disappears after catalog convergence. Preserve the existing list when a POST omits it, while allowing an explicitly submitted value to win.

AGENTS.md reference: src/AGENTS.md:L10-L10

Useful? React with 👍 / 👎.

Comment on lines +579 to +582
Use `retainModels` for the opposite problem: a provider whose `/models` endpoint omits an id that is
still callable (a private deployment, a preview id, an OpenAI-compatible gateway with a partial
listing). Listed ids are kept in the routed catalog with the same context and effort hints as
`models`, and they survive `liveModels: false` too. `selectedModels` still narrows what is visible,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile the static-catalog documentation

This paragraph correctly says retained IDs survive liveModels: false, but lines 570–571 in the same section still state that this mode exposes only models and exposes nothing when models is absent. A retainModels-only configuration now exposes retained rows, as the new runtime path and regression test demonstrate, so the contradictory earlier statement can mislead operators about which models remain visible; describe the static result as the union of models and retainModels.

AGENTS.md reference: docs-site/AGENTS.md:L7-L10

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants