using AuthorBuddy.Web.Models; using Ollama; namespace AuthorBuddy.Web.Services; public class OllamaService : IOllamaService, IDisposable { private readonly OllamaSettings _settings; private OllamaApiClient? _client; private string _currentUrl = "http://localhost:11434"; public OllamaService(OllamaSettings settings) { _settings = settings; _currentUrl = settings.OllamaUrl; _client = new OllamaApiClient(baseUri: new Uri(_currentUrl)); } public Task ReconfigureAsync(string ollamaUrl) { if (_currentUrl != ollamaUrl) { _currentUrl = ollamaUrl; _client?.Dispose(); _client = new OllamaApiClient(baseUri: new Uri(ollamaUrl)); } return Task.CompletedTask; } private OllamaApiClient Client => _client ??= new OllamaApiClient(baseUri: new Uri(_currentUrl)); public async Task> GetLocalModelsAsync() { var models = await Client.Models.ListModelsAsync(); return models.Models ?? Enumerable.Empty(); } public async Task PullModelAsync(string modelName, IProgress progress) { var p = new ModelStatus(); await foreach (var response in Client.Models.PullModelAsync(modelName)) { p.SetModelStatus(response); progress?.Report(p); } } public async Task> GetEmbeddingAsync(string text) { var response = await Client.Embeddings.GenerateEmbeddingAsync( model: _settings.EmbedModel, prompt: text); return response.Embedding ?? Array.Empty(); } public async Task StreamStyleCheckAsync(string input) { var systemPrompt = _settings.LektorSystemPrompt; var chat = Client.Chat(_settings.ChatModel, systemPrompt); var message = await chat.SendAsync(input); return message.Content; } public async Task AnswerBasedOnFactsAsync(string question, string facts) { var prompt = _settings.GetFactCheckPrompt(question, facts); var chat = Client.Chat(_settings.ChatModel); var message = await chat.SendAsync(prompt); return message.Content; } public async Task QuickSpellCheckAsync(string text) { var systemPrompt = _settings.SpellingPrompt; var chat = Client.Chat(_settings.SpellingModel, systemPrompt); var message = await chat.SendAsync(text); return message.Content; } public void Dispose() { _client?.Dispose(); } }