Skip to content

fix(ollama): always respond to model refresh, surface errors, and use form-edited base URL#878

Open
navedmerchant wants to merge 1 commit into
mainfrom
ollama_fetch_fix
Open

fix(ollama): always respond to model refresh, surface errors, and use form-edited base URL#878
navedmerchant wants to merge 1 commit into
mainfrom
ollama_fetch_fix

Conversation

@navedmerchant

@navedmerchant navedmerchant commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #877

Description

This PR fixes the Ollama model refresh flow so the settings panel always gives the user feedback and uses the URL they're actually looking at. The key implementation details:

Extension handler (webviewMessageHandler.ts)

  • The requestOllamaModels case now prefers baseUrl / apiKey from the incoming message values (which reflect the user's unsaved form edits) over the saved extension state, falling back to state only when values are absent. This lets a user validate a URL before saving it.
  • The handler always posts an ollamaModels response back to the webview — even when no models are found — so the UI can transition out of the loading state instead of hanging forever.
  • On fetch failure, the error is now logged to the output channel via provider.log(...) and an empty ollamaModels response is posted with the error message included, so the webview can display it directly. The previous console.debug silent swallow is removed.

Webview (ApiOptions.tsx)

  • The requestOllamaModels message dispatched on provider switch now includes values: { baseUrl, apiKey } from the current apiConfiguration, matching the new handler contract.

Ollama settings component (Ollama.tsx)

  • Replaced the useEvent hook from react-use with a native window.addEventListener("message", ...) inside a useEffect (with proper cleanup), removing the react-use dependency from this component.
  • Added a refreshStatus state machine (idleloadingsuccess | error) and a refreshError state to hold the backend error message.
  • Added a dedicated Refresh Models button (using the shared Button component) that shows a spinner while loading, disables itself during refresh, and displays success / error status text below the button. The error text prefers the backend-provided message and falls back to a localized generic error string.
  • The message listener only transitions status when the component is in the loading state, so unsolicited ollamaModels messages (e.g. from mount refresh) don't clobber the status display.

Test Procedure

Unit tests — extension handler (src/core/webview/__tests__/webviewMessageHandler.spec.ts)

  • cd src && npx vitest run core/webview/__tests__/webviewMessageHandler.spec.ts
  • New cases verify: empty models response is posted when no models found; error response with message is posted and logged on fetch failure; baseUrl/apiKey from message values take precedence over saved state.

Unit tests — Ollama component (webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx)

  • cd webview-ui && npx vitest run src/components/settings/providers/__tests__/Ollama.spec.tsx
  • New describe("Ollama Component - refresh models") block verifies: idle button render, correct requestOllamaModels payload with values on click, loading/disabled state, success state on models arrival, error state on empty models, backend error message display, and no-op for unsolicited messages when not loading.

Manual testing

  1. Select the Ollama provider in settings with Ollama not running.
  2. Click "Refresh Models" — the button shows a spinner, then displays the error message (e.g. "Connection refused") in red.
  3. Start Ollama, click refresh again — the button shows a success status and the model picker populates.
  4. Edit the base URL field but click refresh before saving — the refresh now queries the newly typed URL, not the stale saved one.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to approved GitHub Issue [BUG] Ollama model refresh stuck in loading, silently fails on errors, and uses stale base URL #877.
  • Scope: My changes are focused on the linked issue (Ollama refresh UX).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and updated tests have been added covering the handler and component changes.
  • Documentation Impact: I have considered documentation updates (see below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

N/A — the refresh button and status text use existing shared UI primitives (Button, codicon icons, VS Code CSS variables) with no new visual design.

Documentation Updates

  • No documentation updates are required. The refresh button is self-explanatory and uses existing localized strings (settings:providers.refreshModels.*).

Additional Notes

The react-use useEvent import was removed from Ollama.tsx in favor of a native useEffect-based listener. This is a minor cleanup that reduces the component's dependency surface and makes the listener lifecycle explicit. The corresponding test mock for react-use was also removed.

Get in Touch

navedmerchant (GitHub) / navedmerchant on Discord

Summary by CodeRabbit

  • New Features

    • Added a refresh button for Ollama models in provider settings.
    • Added loading, success, and error feedback during model refreshes.
    • Refresh requests now use the currently configured Ollama URL and API key.
  • Bug Fixes

    • Ollama model requests now consistently return results or display errors.
    • Improved handling when no models are available or model retrieval fails.
  • Tests

    • Added coverage for model refresh behavior, request configuration, and error states.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The Ollama refresh handler now accepts current form credentials, always returns model data, and surfaces errors. The settings UI adds a refresh button with loading, success, and error states, with tests covering backend responses and frontend interactions.

Changes

Ollama model refresh

Layer / File(s) Summary
Backend refresh response contract
src/core/webview/webviewMessageHandler.ts, src/core/webview/__tests__/webviewMessageHandler.spec.ts
The handler prefers request credentials, always posts ollamaModels, logs failures, and includes error messages in failed responses.
Settings refresh flow
webview-ui/src/components/settings/ApiOptions.tsx, webview-ui/src/components/settings/providers/Ollama.tsx, webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx
The UI sends current credentials, adds refresh status state and controls, renders results or errors, and tests the refresh interaction.

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

Suggested labels: awaiting-review

Suggested reviewers: taltas, hannesrudolph, edelauna, JamesRobert20

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the Ollama refresh fix, including response handling, error surfacing, and using edited base URL values.
Description check ✅ Passed The description follows the template with issue link, summary, testing steps, checklist, screenshots, docs, and extra notes.
Linked Issues check ✅ Passed The PR addresses #877 by always returning model responses, surfacing errors, using unsaved values, and adding refresh UI/tests.
Out of Scope Changes check ✅ Passed The changes stay focused on the Ollama refresh flow; the listener refactor and test updates directly support the stated fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 ollama_fetch_fix

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.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ew-ui/src/components/settings/providers/Ollama.tsx 92.00% 0 Missing and 2 partials ⚠️
src/core/webview/webviewMessageHandler.ts 83.33% 0 Missing and 1 partial ⚠️
webview-ui/src/components/settings/ApiOptions.tsx 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx (1)

232-355: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Missing coverage for the "preserve models on refresh error" scenario.

Given the model-list-wipe issue flagged in Ollama.tsx (setting ollamaModels to {} on any error response), consider adding a test that: loads models successfully first, then triggers a refresh that fails, and asserts the previously loaded models remain in ollamaModels/the picker.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx`
around lines 232 - 355, Add coverage in the “Ollama Component - refresh models”
tests for preserving previously loaded models after a failed refresh: complete
one successful refresh, trigger another refresh, dispatch an error response, and
assert the existing model remains visible in the picker or otherwise unchanged.
Use the existing dispatchMessage helper and refresh-button flow, and verify the
error state is shown without clearing the prior model.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx`:
- Around line 74-80: Update the `vi.mock("`@src/components/ui`", ...)` setup in
`Ollama.spec.tsx` to preserve the real barrel exports via `vi.importActual()`
and override only `Button`; ensure `ModelPicker` and `ThinkingBudget` continue
receiving their actual UI dependencies while the test-specific button behavior
remains.

---

Nitpick comments:
In `@webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx`:
- Around line 232-355: Add coverage in the “Ollama Component - refresh models”
tests for preserving previously loaded models after a failed refresh: complete
one successful refresh, trigger another refresh, dispatch an error response, and
assert the existing model remains visible in the picker or otherwise unchanged.
Use the existing dispatchMessage helper and refresh-button flow, and verify the
error state is shown without clearing the prior model.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c7ef33f-2b62-4f1b-a1ac-fee40638bb54

📥 Commits

Reviewing files that changed from the base of the PR and between 116b70e and eff47f7.

📒 Files selected for processing (5)
  • src/core/webview/__tests__/webviewMessageHandler.spec.ts
  • src/core/webview/webviewMessageHandler.ts
  • webview-ui/src/components/settings/ApiOptions.tsx
  • webview-ui/src/components/settings/providers/Ollama.tsx
  • webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx

Comment on lines +74 to +80
// Stub the shared Button so we can assert onClick/disabled without its styling deps.
vi.mock("@src/components/ui", () => ({
Button: ({ children, onClick, disabled, className }: any) => (
<button onClick={onClick} disabled={disabled} className={className} data-testid="refresh-button">
{children}
</button>
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n "from \"`@src/components/ui`\"" webview-ui/src/components/settings -A1 -g '!**/__tests__/**'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 3680


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## Ollama provider\n'
ast-grep outline webview-ui/src/components/settings/providers/Ollama.tsx --view expanded || true
printf '\n## Test file outline\n'
ast-grep outline webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx --view expanded || true

printf '\n## Ollama.tsx relevant lines\n'
nl -ba webview-ui/src/components/settings/providers/Ollama.tsx | sed -n '1,220p'

printf '\n## Ollama.spec.tsx relevant lines\n'
nl -ba webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx | sed -n '1,420p'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 438


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## Search for sibling components used by Ollama/provider test path\n'
rg -n "ModelPicker|ThinkingBudget|Checkbox|VSCodeTextField|refresh-model|refreshModels|loading" webview-ui/src/components/settings/providers webview-ui/src/components/settings -g '!**/__tests__/**' -A3 -B3

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 50378


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## Direct usage of settings subcomponents inside Ollama-related files\n'
rg -n "ModelPicker|ThinkingBudget|Checkbox|VSCodeTextField" webview-ui/src/components/settings -g '!**/__tests__/**' -A2 -B2

printf '\n## Ollama.tsx imports and JSX\n'
nl -ba webview-ui/src/components/settings/providers/Ollama.tsx | sed -n '1,220p'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

nl -ba webview-ui/src/components/settings/ModelPicker.tsx | sed -n '1,260p'

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 199


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## ModelPicker.tsx\n'
awk '{printf "%d:%s\n", NR, $0}' webview-ui/src/components/settings/ModelPicker.tsx | sed -n '1,260p'

printf '\n## UI barrel imports in settings subtree\n'
rg -n "from \"`@src/components/ui`\"" webview-ui/src/components/settings/ModelPicker.tsx webview-ui/src/components/settings/ThinkingBudget.tsx webview-ui/src/components/settings/providers/Ollama.tsx -A2 -B2

Repository: Zoo-Code-Org/Zoo-Code

Length of output: 10832


Mock only Button here. ModelPicker and ThinkingBudget also import symbols from @src/components/ui, so this full barrel mock can turn those dependencies into undefined and make the render brittle. Use vi.importActual() and override just Button.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webview-ui/src/components/settings/providers/__tests__/Ollama.spec.tsx`
around lines 74 - 80, Update the `vi.mock("`@src/components/ui`", ...)` setup in
`Ollama.spec.tsx` to preserve the real barrel exports via `vi.importActual()`
and override only `Button`; ensure `ModelPicker` and `ThinkingBudget` continue
receiving their actual UI dependencies while the test-specific button behavior
remains.

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 11, 2026
@taltas

taltas commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@roomote Please review this PR

@roomote

roomote Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

I saw the mention, but I could not start work on this PR with the current Roomote GitHub setup.

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

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Ollama model refresh stuck in loading, silently fails on errors, and uses stale base URL

2 participants