| 395 | } |
| 396 | |
| 397 | bool QmitknnInteractiveToolGUI::Install() |
| 398 | { |
| 399 | const auto venvName = this->GetTool()->GetVirtualEnvName(); |
| 400 | |
| 401 | // If the venv already exists with nnInteractive installed, skip the install |
| 402 | // dialog: reconcile the recorded install mode, run the version check, and offer |
| 403 | // an in-place update if one is needed. |
| 404 | if (mitk::PythonHelper::VirtualEnvExists(venvName)) |
| 405 | { |
| 406 | if (!this->GetTool()->CreatePythonContext()) |
| 407 | return false; |
| 408 | |
| 409 | if (this->GetTool()->IsInstalled()) |
| 410 | { |
| 411 | // A context exists here, so the find_spec probe is cheap. Reconcile the |
| 412 | // recorded install mode with what is actually installed (e.g. a venv built |
| 413 | // by a different MITK version) so the GUI and preferences adapt correctly. |
| 414 | const bool localAvailable = this->GetTool()->IsLocalInferenceAvailable(); |
| 415 | const std::string installMode = localAvailable ? "full" : "client"; |
| 416 | |
| 417 | if (m_Preferences->Get("nnInteractive/installMode", "full") != installMode) |
| 418 | m_Preferences->Put("nnInteractive/installMode", installMode); |
| 419 | |
| 420 | // Client-only can only run remote sessions; keep the inference mode consistent. |
| 421 | if (!localAvailable && m_Preferences->Get("nnInteractive/inferenceMode", "local") != "remote") |
| 422 | m_Preferences->Put("nnInteractive/inferenceMode", "remote"); |
| 423 | |
| 424 | const std::string distributionName = localAvailable ? "nnInteractive" : "nninteractive-client"; |
| 425 | |
| 426 | // A reused virtual environment can hold an nnInteractive that predates this |
| 427 | // MITK build (the venv survives MITK upgrades). The offline minimum check |
| 428 | // runs on every initialize; the online "newer release available" check runs |
| 429 | // at most once per application run so an offline user never waits on the |
| 430 | // PyPI timeout repeatedly. |
| 431 | const bool checkForUpdate = !onlineUpdateCheckDone; |
| 432 | const auto versionCheck = mitk::nnInteractive::CheckInstalledVersion( |
| 433 | *this->GetTool()->GetPythonContext(), checkForUpdate, distributionName); |
| 434 | |
| 435 | // Attempt-based: the PyPI query blocks the GUI for up to its 5 s timeout, |
| 436 | // so even a failed (offline) attempt counts and is not repeated this run. |
| 437 | if (checkForUpdate) |
| 438 | onlineUpdateCheckDone = true; |
| 439 | |
| 440 | if (versionCheck.Status == mitk::nnInteractive::VersionStatus::BelowMinimum || |
| 441 | versionCheck.Status == mitk::nnInteractive::VersionStatus::UpdateAvailable) |
| 442 | { |
| 443 | if (!this->OfferInPlaceUpdate(versionCheck, !localAvailable)) |
| 444 | return false; |
| 445 | } |
| 446 | |
| 447 | // Offer to adopt a newer recommended model checkpoint (full + local only). |
| 448 | this->MaybePromptModelSwitch(localAvailable); |
| 449 | |
| 450 | return true; |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | // Fresh install: let the user choose between a full and a client-only install. |
nothing calls this directly
no test coverage detected