Skip to content

commit the provider list as soon as its own fetch settles, and say so while it loads - #6088

Merged
atomantic merged 1 commit into
mainfrom
cos/task-mtlpvm4j/agent-0c68e414
Sep 3, 2026
Merged

commit the provider list as soon as its own fetch settles, and say so while it loads#6088
atomantic merged 1 commit into
mainfrom
cos/task-mtlpvm4j/agent-0c68e414

Conversation

@atomantic

Copy link
Copy Markdown
Owner

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. /providers is a cache-only read that returns in milliseconds, but ChiefOfStaff.fetchData bundled it into a five-way Promise.all and committed the result only 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 a future writer can't set providers without stamping the settle flag.
  • 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, since providers is an unmemoized prop down through every schedule card.

Empty-vs-unsettled. An empty providers array is ambiguous: "still fetching" and "none configured" both render a picker offering only the caller's emptyProviderOption. ProviderModelSelector gains a loading prop 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 a loading flag nobody reads) and the same head-of-line block still affecting getApps.

Test plan

  • client suite: 10178 passed, 2 skipped, 0 failed
  • npm run lint (biome): clean
  • New coverage:
    • ProviderModelSelector.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 settles
    • AppTaskCard.test.jsx — the card actually threads the flag through to the picker

…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`.
@atomantic
atomantic merged commit 6bf092b into main Sep 3, 2026
7 checks passed
@atomantic
atomantic deleted the cos/task-mtlpvm4j/agent-0c68e414 branch September 3, 2026 16:28
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