commit the provider list as soon as its own fetch settles, and say so while it loads - #6088
Merged
Merged
Conversation
…four slower reads The CoS Schedule page showed a provider picker with a single "Default (active provider)" option for seconds after load, which reads as a broken control rather than a slow one. Two causes, both fixed here: `/providers` is a cache-only read that returns in milliseconds, but ChiefOfStaff bundled it into a five-way `Promise.all` and only committed the result after the slowest sibling settled — and `getCosActionableInsights` runs a server-side PM2/memory health check plus a cross-repo git scan. Providers now commit on their own settle, mirroring the `healthRead` split four lines above. `applyProviders` is the single write path (as `applyHealth` is for health), so the settle flag can't be skipped by a future writer, and a `sameJsonShape` guard keeps the array identity stable when the payload is unchanged — otherwise the earlier commit would cost a full-tree re-render on every 30s poll. An empty `providers` array is also ambiguous: "still fetching" and "none configured" both render a picker whose only choice is the caller's `emptyProviderOption`. `ProviderModelSelector` gains a `loading` prop that disables its selects and says "Loading providers…" instead — the same settle-gate it already applies to its own tool-use capability scan. Wired through the Schedule tab: the card's quick pins and all three pickers in the task config drawer, so no picker sits enabled-but-empty beside a disabled one. Remaining pickers (Tasks/Agents/Workflow tabs, and the ~15 that fetch through useProviderModels, which already returns a `loading` flag nobody reads) are tracked in #6087, along with the same head-of-line block on `getApps`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The CoS Schedule page rendered a provider picker whose only option was "Default (active provider)" for seconds after load — a slow control that reads as a broken one.
Latency.
/providersis a cache-only read that returns in milliseconds, butChiefOfStaff.fetchDatabundled it into a five-wayPromise.alland committed the result only after the slowest sibling settled — andgetCosActionableInsightsruns a server-side PM2/memory health check plus a cross-repo git scan. Providers now commit on their own settle, mirroring thehealthReadsplit four lines above.applyProvidersis the single write path (asapplyHealthis for health), so a future writer can't setproviderswithout stamping the settle flag.sameJsonShapeguard keeps the array identity stable when the payload is unchanged — otherwise the earlier commit would cost a full-tree re-render on every 30s poll, sinceprovidersis an unmemoized prop down through every schedule card.Empty-vs-unsettled. An empty
providersarray is ambiguous: "still fetching" and "none configured" both render a picker offering only the caller'semptyProviderOption.ProviderModelSelectorgains aloadingprop that disables its three selects and says "Loading providers…" instead — the same settle-gate it already applies to its own tool-use capability scan, now applied to the list the caller owns.Wired through the Schedule tab: the card's quick pins and all three pickers in the task config drawer, so no picker sits enabled-but-empty beside a disabled one.
Follow-up
#6087 tracks the remaining pickers (Tasks/Agents/Workflow tabs, plus the ~15 that fetch through
useProviderModels— which already returns aloadingflag nobody reads) and the same head-of-line block still affectinggetApps.Test plan
clientsuite: 10178 passed, 2 skipped, 0 failednpm run lint(biome): cleanProviderModelSelector.test.jsx— the loading option replaces the caller's sentinel, renders even when the caller forces a selection, disables the model select, and reverts once the list settlesAppTaskCard.test.jsx— the card actually threads the flag through to the picker