Skip to content

Fix local model download progress after Notes navigation#1052

Open
dpersek wants to merge 3 commits into
OpenWhispr:mainfrom
dpersek:fix/notes-local-model-download-state
Open

Fix local model download progress after Notes navigation#1052
dpersek wants to merge 3 commits into
OpenWhispr:mainfrom
dpersek:fix/notes-local-model-download-state

Conversation

@dpersek

@dpersek dpersek commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Persist active local LLM download status in the model listing returned to the renderer, including active state and progress bytes.
  • Rehydrate local model download progress when the picker remounts after navigation, and handle duplicate in-progress clicks without clearing the active download UI.
  • Emit completion/error events for local LLM downloads so remounted picker flows can refresh or clear state when the original component is gone.
  • Add a focused regression test for the main-process model status surface.

Why

Fixes #1007.

When a user starts a local model download from the Notes get-started flow, navigates away, and returns, the renderer loses its in-memory progress state even though the main process is still downloading. This makes the download look unavailable or stuck and turns retry clicks into a duplicate in-progress failure instead of showing the existing download.

Tests

  • npm run lint -> passed. It still emits the existing Node module-type warning for src/eslint.config.js.
  • npm run typecheck -> passed.
  • node --test test/helpers/modelManagerBridgeDownloadStatus.test.js -> passed, 1 test.
  • node --check src/helpers/modelManagerBridge.js -> passed.
  • node --check src/helpers/ipcHandlers.js -> passed.
  • node --check test/helpers/modelManagerBridgeDownloadStatus.test.js -> passed.
  • prettier --check src/helpers/ModelManager.ts src/helpers/ipcHandlers.js src/helpers/modelManagerBridge.js src/hooks/useLocalModels.ts src/hooks/useModelDownload.ts src/types/electron.ts test/helpers/modelManagerBridgeDownloadStatus.test.js -> passed.
  • git diff --check -> passed.
  • npm run format:check -> failed on pre-existing unrelated formatting issues in src/helpers/audioManager.js, src/helpers/speakerEmbeddings.js, and src/helpers/textEditMonitor.js.

Scope

  • Local LLM model download state, IPC events, picker hydration, and focused regression coverage.
  • Non-goals: cloud providers, transcription pipeline, model registry content, dependencies, and lockfile changes.

Caveats

  • I did not run a manual Electron download smoke test because that would require a large real model download. The automated coverage verifies the main-process status surface that remounted renderer flows depend on, and the renderer changes were checked with lint/typecheck.
  • Full format check is blocked by unrelated pre-existing files listed above; the changed files pass Prettier.

@dpersek
dpersek marked this pull request as ready for review July 5, 2026 19:48
@Chadpiha

Copy link
Copy Markdown
Collaborator

I added two follow-up commits after reviewing and testing the original implementation locally.

1. Preserve local LLM download state across picker remounts

The first commit hardened the original GGUF/local LLM path:
Rehydrates active download progress when the picker remounts.
Preserves the existing progress UI when a duplicate download request returns DOWNLOAD_IN_PROGRESS.
Emits and handles completion/error events when the initiating component is no longer mounted.
Prevents cancellation from also displaying a failure dialog.
Avoids clearing progress before the downloaded-model list refresh completes.
Adds focused regression coverage for the main-process model status surface.

2. Extend persistence to Whisper and Parakeet transcription models

Local testing showed that the Notes settings flow I was reproducing used a Parakeet transcription model, while the original fix only covered modelType === "llm". I therefore generalized the solution to the actual Whisper/Parakeet paths:
Exposes active download, byte progress, and Parakeet installation state through the existing model-list IPC APIs.
Rehydrates Whisper and Parakeet progress after closing and reopening settings.
Adopts progress and terminal events in a newly mounted picker.
Adds main-process duplicate-download guards to prevent concurrent writers corrupting the same temporary file.
Keeps cancellation guards active until download cleanup finishes.
Disables Parakeet cancellation once archive extraction has started.
Serializes completion refreshes so stale model-list requests cannot restore the Download button after installation.
Adds regression tests for status hydration, duplicate protection, cancellation behavior, and Whisper completion events.

These changes were made because the original approach was correct for local LLMs, but did not cover the transcription model flow that exposed the reported Notes/settings behavior. All focused tests, typecheck, lint, Prettier, and diff checks pass.

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.

Unable to download local model after navigating away from get started screen in Notes space.

2 participants