Skip to content

🍱 feat: Reload Custom Model Lists Across Replicas - #16470

Closed
lia-by-librechat[bot] wants to merge 1 commit into
canaryfrom
lia/reload-model-catalog-canary
Closed

lia-by-librechat[bot] wants to merge 1 commit into
canaryfrom
lia/reload-model-catalog-canary

Conversation

@lia-by-librechat

Copy link
Copy Markdown
Contributor

Summary

Changing the default model list for an existing custom endpoint in librechat.yaml currently requires restarting every API replica. This PR validates a local or HTTP(S) CONFIG_PATH on an explicit admin reload, installs only existing custom endpoints' models.default changes, and reports every other YAML edit as requiring a restart. A new endpoint, changed credentials, memory policy, MCP settings, tool filters, and startup configuration never take effect through this reload.

The control appears in General settings only for a user with platform-scoped MANAGE_CONFIGS and ACCESS_ADMIN. It checks access when settings opens, not during every authenticated startup-config request. The POST independently enforces both grants. A model picker already open in another browser observes the applied replica generation and refreshes its models only after a serving replica proves it has that version.

Supersedes the closed broad-scope PR #16385. Builds on the last-good reload behavior already merged in #16383. Targets canary for an explicit operator rollout.

How it works

Admin POST → read and validate all YAML → report + project only existing custom models.default
           → install locally → compare-and-publish model-catalog:v1 generation in Redis
Other replica → background Redis check → reload its own source → install only on digest match
Open browser → poll authenticated local revision → fetch models with matching version header

A slower admin reload cannot overwrite a newer Redis generation. A replica whose source has not caught up retains its last good model list and retries at a configurable rate; publication is not a claim that all replicas have applied it. Only the process-local APP_CONFIG cache stores the accepted base. Redis is optional: without it, the operation and report are explicitly local-only. The initial Redis read is bounded; a server can start during a Redis outage and continue serving its last good config.

Rollout: configReload.clusterReady defaults to false. After all replicas run this version, enable it in the source configuration and restart them before invoking reload. The new Redis key is versioned and isolated from the previous broad reload protocol. Do not perform clustered reloads during a mixed-version rollout. configReload.clientPollIntervalMs and configReload.mismatchRetryMs default to 3000 ms and 5000 ms respectively; remote fetches retain the previous 10-second timeout unless configured.

Type of change

  • Feature
  • Tests

Testing

  • Focused TypeScript backend tests for projection, generation fencing, lagging replicas, failures and authorization; focused Express route and client control/model-picker tests.
  • Real Redis and an HTTP config source with two independent Node API processes: one publishes, a lagging second keeps its old model list, then applies the new list after its source catches up; prefixed Redis key and invalid YAML retaining the last good config verified.
  • tsc --noEmit in packages/data-provider, packages/api, and client; builds of packages/data-provider, packages/data-schemas, packages/api, and packages/client; staged npm run static-checks (all affected gates passed).
  • Local Lighthouse and full Playwright browser suites were not run because no Chrome/Playwright browser is installed in this worker. CI should run the Lighthouse and browser lanes on this pushed head.

Risk / compatibility

Only default model lists for existing, uniquely named custom endpoints can change live. Other edits remain at each replica's startup value, including values used by the expired-file sweep, GitHub skill synchronization, MCP recovery, and global static tool catalog. Source-validation errors leave the last good base intact. Redis publication uses a single-key Lua compare-and-publish, and a published generation never exposes YAML or configuration secrets. MongoDB config override priority remains unchanged. An unavailable Redis store permits a local-only reload and reports propagation failure without blocking normal cached requests.

Checklist

  • Relevant regression tests added
  • Local focused checks passed
  • Lighthouse and full browser CI pending

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Please review exact head d5a8bdad6a5b97806e903d3d2cfbe5863b98d90d. It restricts live YAML changes to existing custom endpoint default-model lists, protects Redis publication with a versioned compare-and-publish protocol, requires platform-scoped grants, and refreshes an existing browser picker only from an applied replica. Local focused backend, route and UI tests, all changed workspace typechecks, staged static checks, and a real two-process HTTP/Redis smoke passed. Lighthouse is running locally and CI is starting.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Superseded by #16471, the same narrow model-list reload carried onto current dev without canary-only commits. Closing this canary PR so there is one merge target; the branch remains intact.

@lia-by-librechat lia-by-librechat Bot closed this Sep 28, 2026
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.

1 participant