Add error handle

This commit is contained in:
vanzue
2025-11-15 20:23:26 +08:00
parent 24a3cdd486
commit b3522b1673
4 changed files with 53 additions and 19 deletions

View File

@@ -180,15 +180,9 @@ internal sealed class FoundryClient
return true;
}
// Check if model exists in cache
var cachedModels = await ListCachedModels().ConfigureAwait(false);
Logger.LogInfo($"[FoundryClient] Cached models: {string.Join(", ", cachedModels.Select(m => m.Name))}");
if (!cachedModels.Any(m => m.Name == modelId))
{
Logger.LogWarning($"[FoundryClient] Model not found in cache: {modelId}");
return false;
}
// Do not check if model exists in cache as this is not reliable
// var cachedModels = await ListCachedModels().ConfigureAwait(false);
// Logger.LogInfo($"[FoundryClient] Cached models: {string.Join(", ", cachedModels.Select(m => m.Name))}");
// Load the model
Logger.LogInfo($"[FoundryClient] Loading model: {modelId}");

View File

@@ -13,6 +13,7 @@ namespace LanguageModelProvider;
public sealed class FoundryLocalModelProvider : ILanguageModelProvider
{
private IEnumerable<ModelDetails>? _downloadedModels;
private IEnumerable<FoundryCatalogModel>? _catalogModels;
private FoundryClient? _foundryClient;
private string? _serviceUrl;
@@ -47,6 +48,24 @@ public sealed class FoundryLocalModelProvider : ILanguageModelProvider
return null;
}
// Check if model is in catalog
var isInCatalog = _catalogModels?.Any(m => m.Name == modelId) ?? false;
if (!isInCatalog)
{
var errorMessage = $"{modelId} is not supported in Foundry Local. Please configure supported models in Settings.";
Logger.LogError($"[FoundryLocal] {errorMessage}");
throw new InvalidOperationException(errorMessage);
}
// Check if model is cached
var isInCache = _downloadedModels?.Any(m => m.ProviderModelDetails is FoundryCachedModel cached && cached.Name == modelId) ?? false;
if (!isInCache)
{
var errorMessage = $"The requested model '{modelId}' is not cached. Please download it using Foundry Local.";
Logger.LogError($"[FoundryLocal] {errorMessage}");
throw new InvalidOperationException(errorMessage);
}
// Ensure the model is loaded before returning chat client
try
{
@@ -122,12 +141,13 @@ public sealed class FoundryLocalModelProvider : ILanguageModelProvider
private void Reset()
{
_downloadedModels = null;
_catalogModels = null;
_ = InitializeAsync();
}
private async Task InitializeAsync(CancellationToken cancelationToken = default)
{
if (_foundryClient != null && _downloadedModels != null && _downloadedModels.Any())
if (_foundryClient != null && _downloadedModels != null && _downloadedModels.Any() && _catalogModels != null && _catalogModels.Any())
{
await _foundryClient.EnsureRunning().ConfigureAwait(false);
return;
@@ -145,6 +165,10 @@ public sealed class FoundryLocalModelProvider : ILanguageModelProvider
_serviceUrl ??= await _foundryClient.GetServiceUrl();
Logger.LogInfo($"[FoundryLocal] Service URL: {_serviceUrl}");
var catalogModels = await _foundryClient.ListCatalogModels();
Logger.LogInfo($"[FoundryLocal] Found {catalogModels.Count} catalog models");
_catalogModels = catalogModels;
var cachedModels = await _foundryClient.ListCachedModels();
Logger.LogInfo($"[FoundryLocal] Found {cachedModels.Count} cached models");

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AdvancedPaste.Helpers;
using AdvancedPaste.Models;
using LanguageModelProvider;
using Microsoft.Extensions.AI;
@@ -33,10 +34,6 @@ public sealed class FoundryLocalPasteProvider : IPasteAIProvider
_config = config;
}
public string ProviderName => AIServiceType.FoundryLocal.ToNormalizedKey();
public string DisplayName => string.IsNullOrWhiteSpace(_config?.Model) ? "Foundry Local" : _config.Model;
public async Task<bool> IsAvailableAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -76,13 +73,20 @@ public sealed class FoundryLocalPasteProvider : IPasteAIProvider
}
cancellationToken.ThrowIfCancellationRequested();
var chatClient = _modelProvider.GetIChatClient(modelReference);
if (chatClient is null)
IChatClient chatClient;
try
{
chatClient = _modelProvider.GetIChatClient(modelReference);
}
catch (InvalidOperationException ex)
{
// GetIChatClient throws InvalidOperationException for user-facing errors
var errorMessage = string.Format(System.Globalization.CultureInfo.CurrentCulture, ResourceLoaderInstance.ResourceLoader.GetString("FoundryLocal_UnableToLoadModel"), modelReference);
throw new PasteActionException(
$"Unable to load Foundry Local model: {modelReference}",
new InvalidOperationException("Chat client resolution failed"),
aiServiceMessage: "The model may not be downloaded or the Foundry Local service may not be running. Please check the model status in settings.");
errorMessage,
ex,
aiServiceMessage: ex.Message);
}
var userMessageContent = $"""

View File

@@ -368,4 +368,16 @@
<value>Local</value>
<comment>Badge label displayed next to local AI model providers (e.g., Ollama, Foundry Local) to indicate the model runs locally</comment>
</data>
<data name="FoundryLocal_ModelNotSupported" xml:space="preserve">
<value>{0} is not supported in Foundry Local. Please configure supported models in Settings.</value>
<comment>{0} is the model identifier. Do not translate {0}.</comment>
</data>
<data name="FoundryLocal_ModelNotCached" xml:space="preserve">
<value>The requested model '{0}' is not cached. Please download it using Foundry Local.</value>
<comment>{0} is the model identifier. Do not translate {0}.</comment>
</data>
<data name="FoundryLocal_UnableToLoadModel" xml:space="preserve">
<value>Unable to load Foundry Local model: {0}</value>
<comment>{0} is the model identifier. Do not translate {0}.</comment>
</data>
</root>