Skip to content

fix: model picker stays usable during provider loading#8900

Merged
kalvinnchau merged 6 commits intomainfrom
model-selection-becomes-unavailable
Apr 29, 2026
Merged

fix: model picker stays usable during provider loading#8900
kalvinnchau merged 6 commits intomainfrom
model-selection-becomes-unavailable

Conversation

@matt2e
Copy link
Copy Markdown
Collaborator

@matt2e matt2e commented Apr 29, 2026

reload.providers.and.model.mov

UI Changes

  • No more "Loading" flash on startup — the model picker button shows the current provider name (e.g. "Claude") or model name instead of briefly flashing "Loading" while providers refresh
  • Button stays clickable — the picker is only disabled when loading AND no provider is already known, so users can interact with it during background refreshes
  • Smarter loading state in dropdown — when models are loading but the current model name is known, shows it as a placeholder item with a spinner instead of a generic "Loading models…" message
  • Background refresh on open — opening the picker triggers a silent inventory refresh so newly available models/providers appear without an app restart

Implementation

  1. Reorder button label priority (AgentModelPicker.tsx) — Display triggerModelLabel ?? selectedAgentLabel first; only fall back to "Loading" when neither is available. Conditionally disable the button only when loading && !selectedAgentLabel.

  2. Deduplicate startup RPC (useAppStartup.ts, acp.ts, acpApi.ts) — Merge loadProviders and loadProviderInventory into a single loadProvidersAndInventory call. Extract buildProviderListFromEntries() so both listProviders() and the startup path can derive the provider list from the same inventory response, eliminating a redundant _goose/providers/list RPC.

  3. Extract shared background refresh (inventory.ts) — Move the refresh+poll loop (refresh configured providers, poll with delays until all finish) into a reusable backgroundRefreshInventory() function. It merges results into the store without setting loading=true, so cached data stays visible during the refresh.

  4. Background refresh on picker open (useAgentModelPickerState.ts) — Add a handlePickerOpen callback that triggers backgroundRefreshInventory() when the popover opens (guarded by a ref to prevent concurrent refreshes). This replaces the old useEffect in AgentModelPicker that called getProviderInventory() on every open and merged results synchronously.

  5. Thread onPickerOpen through the component tree — Wire handlePickerOpen from the hook through useResolvedAgentModelPickeruseChatSessionControllerChatView/HomeScreenChatInputChatInputToolbarAgentModelPicker's onOpen prop, which fires on onOpenChange(true).

Copy link
Copy Markdown

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

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: eac93b5dc3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread ui/goose2/src/features/chat/ui/AgentModelPicker.tsx
@matt2e matt2e changed the title fix: prevent model picker from becoming disabled during loading fix: model picker stays usable during provider loading Apr 29, 2026
Comment thread ui/goose2/src/features/providers/api/inventory.ts Outdated
matt2e and others added 6 commits April 29, 2026 10:52
…startup

Change the button display priority so triggerModelLabel and
selectedAgentLabel take precedence over the loading state. Previously,
providersLoading=true would unconditionally show "Loading" even when a
meaningful label (e.g. "Claude") was already available, causing a jarring
"Claude" → "Loading" → "sonnet[1m]" flash on startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only disable the button when loading AND no selectedAgentLabel is
available. Previously the button was unconditionally disabled during
provider loading, preventing interaction even when a provider was
already selected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove the redundant getProviderInventory() call that fired every time
  the picker popover opened, duplicating work already done by
  useAppStartup's polling
- When models are loading but the current model name is already known,
  show it as a placeholder item with a spinner instead of a generic
  "Loading models" message, keeping the dropdown consistent with the
  button label

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract the refresh+poll logic from useAppStartup into a shared
backgroundRefreshInventory() function in inventory.ts. When the user
opens the model picker popover, trigger a background inventory refresh
that updates the model list in-place without showing a loading state.
This ensures newly available models/providers are discovered after
credential or config changes without requiring an app restart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Background inventory refresh fetched the current provider inventory when
opened from the model picker, but only merged results into the store after a
refresh actually started. This meant fresh inventory was discarded when no
providers were configured, refresh was unsupported, providers were already
refreshing, or the refresh response returned no started providers.

Merge the fetched snapshot before those early returns, while preserving the
startup path where initial entries have already been stored.
@kalvinnchau kalvinnchau force-pushed the model-selection-becomes-unavailable branch from 4e71b1d to 25da8d0 Compare April 29, 2026 18:06
@kalvinnchau kalvinnchau enabled auto-merge April 29, 2026 18:08
@kalvinnchau kalvinnchau added this pull request to the merge queue Apr 29, 2026
Merged via the queue into main with commit b4c0879 Apr 29, 2026
26 of 27 checks passed
@kalvinnchau kalvinnchau deleted the model-selection-becomes-unavailable branch April 29, 2026 18:21
lifeizhou-ap added a commit that referenced this pull request Apr 30, 2026
* main: (24 commits)
  fix: copy and content improvements in goose2 (#8886)
  feat: make ollama host configurable in goose2 (#8912)
  polish sidebar navigation and project icons (#8896)
  fix: model picker stays usable during provider loading (#8900)
  feat: update provider row after saving credentials (#8914)
  feat: support google model inventory refresh (#8913)
  chore: Added goose 2 UI refactor review skill (#8903)
  blog: goose with peekaboo (#8884)
  blog: Built-in Local Inference blogpost. (#8808)
  perf: parallelize provider resolution and eagerly init SQLite pool (#8899)
  refactor: update goose2 credential management behind provider-scoped ACP/core API (#8887)
  fix: handle acp requests concurrently (#8781)
  build: set LLAMA_STATIC_CRT for Windows CUDA (#8901)
  perf: deduplicate _goose/providers/list RPC call at startup (#8873)
  chore: add a bit more instructions in the release pr (#8890)
  chore: disable spellcheck in model search (#8889)
  add skills to the chat composer (#8881)
  mergeable configs + cleanup (#8378)
  refactor: agent provider to use explicit type states (#8879)
  [goose2] MCP Apps: hydrate and replay app payloads in Goose2 (#8632)
  ...
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.

3 participants