Skip to content

fix(ui): prevent spinner cycling causing early exit in model selection#2086

Merged
tusharmath merged 8 commits intomainfrom
fix/model-selection-early-exit
Dec 12, 2025
Merged

fix(ui): prevent spinner cycling causing early exit in model selection#2086
tusharmath merged 8 commits intomainfrom
fix/model-selection-early-exit

Conversation

@amitksingh1490
Copy link
Copy Markdown
Contributor

@amitksingh1490 amitksingh1490 commented Dec 8, 2025

Problem

Some users reported that model selection prompts can exit immediately without user input (as if ESC/Ctrl+C) after provider activation. This appears timing/environment dependent.

Root Cause (confirmed)

SpinnerManager::start() spawns a background tracker task that periodically updates the progress bar message.

Previously, SpinnerManager::stop() dropped the tracker task JoinHandle but did not abort it. In Tokio, dropping a JoinHandle detaches the task, so the tracker could continue running after stop() and keep updating the terminal concurrently with interactive prompts (dialoguer/ForgeSelect). This kind of concurrent terminal output can lead to flaky prompt behavior.

Proof (deterministic regression test)

A new unit test demonstrates the issue:

  • Without aborting the tracker task, the test fails because the tracker continues ticking after stop().
  • With aborting the tracker task, the test passes because ticks stop after stop().

Solution

  • Abort the tracker task when stopping the spinner.
  • Add a regression test to ensure the tracker task is stopped after stop().

Notes

  • The earlier ui.rs change (calling self.api.get_models() directly to avoid a double spinner cycle) has been reverted. With the tracker properly stopped, the spinner cycling itself should no longer leave a detached background task running.

Testing

  • cargo test -p forge_spinner
  • cargo check -p forge_main

Co-Authored-By: ForgeCode noreply@forgecode.dev

Fixes an issue where dialoguer prompts would exit early during model
selection after provider activation.

Root cause: The finalize_provider_activation function was calling
self.get_models() which starts/stops a spinner, followed by
on_model_selection() which calls get_models() again, creating rapid
spinner cycling (start→stop→start→stop) before showing the dialoguer
prompt. This terminal manipulation corrupted the terminal state,
causing dialoguer to exit prematurely.

Solution: Changed to call self.api.get_models() directly for the
availability check, bypassing the spinner. This ensures only one
spinner cycle occurs (during the actual model selection), preventing
terminal state corruption.

This issue was introduced in PR #1958 (commit c58fec0) and only
affects v1.9.0.

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
@github-actions github-actions Bot added the type: fix Iterations on existing features or infrastructure. label Dec 8, 2025
Comment thread crates/forge_spinner/src/lib.rs
@tusharmath tusharmath merged commit cf251e3 into main Dec 12, 2025
8 checks passed
@tusharmath tusharmath deleted the fix/model-selection-early-exit branch December 12, 2025 11:57
laststylebender14 pushed a commit that referenced this pull request Dec 16, 2025
#2086)

Co-authored-by: ForgeCode <noreply@forgecode.dev>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix Iterations on existing features or infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants