Advanced Paste: Handle Foundry local Port change on the fly#45362
Advanced Paste: Handle Foundry local Port change on the fly#45362
Conversation
…client to make sure our client function well
There was a problem hiding this comment.
Pull request overview
Updates the Foundry Local provider used by Advanced Paste to better tolerate Foundry Local endpoint/port changes at runtime by refreshing the underlying client and re-resolving the service URL when failures occur.
Changes:
- Refreshes the Foundry Local client when the model isn’t found in the catalog (to handle stale catalog/service state).
- Retries
EnsureModelLoadedwith a client refresh on failure/exception. - Re-fetches service URL during initialization and refreshes when
ServiceUriis unavailable.
| _foundryClient = null; | ||
| _catalogModels = null; | ||
| _serviceUrl = null; | ||
|
|
||
| InitializeAsync().GetAwaiter().GetResult(); |
There was a problem hiding this comment.
TryRefreshClient mutates the singleton’s shared state (_foundryClient/_catalogModels/_serviceUrl) without any synchronization. Since this provider is used from both Settings UI and Advanced Paste, concurrent calls (e.g., GetModelsAsync while a paste action triggers a refresh) can race and produce null dereferences/inconsistent reads. Consider guarding initialization/refresh and all reads of these fields with a lock/SemaphoreSlim, or swapping an immutable state object via Interlocked.Exchange so callers always operate on a consistent snapshot.
| Logger.LogWarning($"[FoundryLocal] Model not found in catalog. Refreshing client for model: {modelId}"); | ||
| if (!TryRefreshClient("Model not in catalog")) | ||
| { | ||
| return false; |
There was a problem hiding this comment.
EnsureModelInCatalog returns false both when the model truly isn’t in the catalog and when refreshing the Foundry client fails. In the refresh-failure case, GetIChatClient will currently throw the "model is not supported" InvalidOperationException, which is misleading (the real issue may be that Foundry Local isn’t reachable/initialized). Consider propagating the refresh failure separately (e.g., throw a more accurate InvalidOperationException when TryRefreshClient fails, or return a result that preserves the failure reason).
| return false; | |
| const string message = "Foundry Local client could not be refreshed. Please make sure Foundry Local is installed and running."; | |
| Logger.LogError($"[FoundryLocal] {message}"); | |
| throw new InvalidOperationException(message); |
Summary of the Pull Request
Foundry Local returns 400 Bad Request if a manual port change made for foundry local.
Fix #45340
PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed
Follow steps described in the issue, and the advanced paste can work without having to restart powertoys itself