From 24b9e88a55087f317c5611f3cc13af53c150663a Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Tue, 19 Nov 2024 12:14:30 +0100 Subject: [PATCH 1/7] Implement settings file for Ollama agent --- .../AIShell.Ollama.Agent/OllamaAgent.cs | 59 ++++++++++++++++++- .../AIShell.Ollama.Agent/OllamaChatService.cs | 13 ++-- shell/agents/AIShell.Ollama.Agent/Settings.cs | 35 +++++++++++ 3 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 shell/agents/AIShell.Ollama.Agent/Settings.cs diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs index 36aa6140..08886226 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs @@ -1,10 +1,20 @@ using System.Diagnostics; +using System.Text; +using System.Text.Json; using AIShell.Abstraction; namespace AIShell.Ollama.Agent; public sealed class OllamaAgent : ILLMAgent { + private const string SettingFileName = "ollama.config.json"; + private Settings _settings; + + /// + /// Gets the settings. + /// + internal Settings Settings => _settings; + /// /// The name of the agent /// @@ -51,7 +61,17 @@ public void Dispose() /// Agent configuration for any configuration file and other settings public void Initialize(AgentConfig config) { - _chatService = new OllamaChatService(); + SettingFile = Path.Combine(config.ConfigurationRoot, SettingFileName); + _settings = ReadSettings(); + + if (_settings is null) + { + // Create the setting file with examples to serve as a template for user to update. + NewExampleSettingFile(); + _settings = ReadSettings(); + } + + _chatService = new OllamaChatService(_settings); LegalLinks = new(StringComparer.OrdinalIgnoreCase) { @@ -68,7 +88,7 @@ public void Initialize(AgentConfig config) /// /// Gets the path to the setting file of the agent. /// - public string SettingFile { private set; get; } = null; + public string SettingFile { private set; get; } /// /// Gets a value indicating whether the agent accepts a specific user action feedback. @@ -122,4 +142,39 @@ public async Task ChatAsync(string input, IShell shell) return true; } + + private Settings ReadSettings() + { + Settings settings = null; + FileInfo file = new(SettingFile); + + if (file.Exists) + { + try + { + using var stream = file.OpenRead(); + var data = JsonSerializer.Deserialize(stream, SourceGenerationContext.Default.ConfigData); + settings = new Settings(data); + } + catch (Exception e) + { + throw new InvalidDataException($"Parsing settings from '{SettingFile}' failed with the following error: {e.Message}", e); + } + } + + return settings; + } + + private void NewExampleSettingFile() + { + string SampleContent = $$""" + { + // Declare Ollama model name. + "Model": "phi3", + // Declare Ollama endpoint. + "Endpoint": "http://localhost:11434/api/generate" + } + """; + File.WriteAllText(SettingFile, SampleContent, Encoding.UTF8); + } } diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs b/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs index 8809eff3..63314dd7 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs @@ -7,11 +7,7 @@ namespace AIShell.Ollama.Agent; internal class OllamaChatService : IDisposable { - /// - /// Ollama endpoint to call to generate a response - /// - internal const string Endpoint = "http://localhost:11434/api/generate"; - + private Settings _settings; /// /// Http client /// @@ -20,8 +16,9 @@ internal class OllamaChatService : IDisposable /// /// Initialization method to initialize the http client /// - internal OllamaChatService() + internal OllamaChatService(Settings settings) { + _settings = settings; _client = new HttpClient(); } @@ -43,7 +40,7 @@ private HttpRequestMessage PrepareForChat(string input) // Main data to send to the endpoint var requestData = new Query { - model = "phi3", + model = _settings.Model, prompt = input, stream = false }; @@ -51,7 +48,7 @@ private HttpRequestMessage PrepareForChat(string input) var json = JsonSerializer.Serialize(requestData); var data = new StringContent(json, Encoding.UTF8, "application/json"); - var request = new HttpRequestMessage(HttpMethod.Post, Endpoint) { Content = data }; + var request = new HttpRequestMessage(HttpMethod.Post, _settings.Endpoint) { Content = data }; return request; } diff --git a/shell/agents/AIShell.Ollama.Agent/Settings.cs b/shell/agents/AIShell.Ollama.Agent/Settings.cs new file mode 100644 index 00000000..7ac3555b --- /dev/null +++ b/shell/agents/AIShell.Ollama.Agent/Settings.cs @@ -0,0 +1,35 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace AIShell.Ollama.Agent; + +internal class Settings +{ + public string Model { get; set; } + public string Endpoint { get; set; } + + public Settings(ConfigData configData) + { + Model = configData.Model; + Endpoint = configData.Endpoint; + } +} + +internal class ConfigData +{ + public string Model { get; set; } + public string Endpoint { get; set; } +} + +/// +/// Use source generation to serialize and deserialize the setting file. +/// Both metadata-based and serialization-optimization modes are used to gain the best performance. +/// +[JsonSourceGenerationOptions( + WriteIndented = true, + AllowTrailingCommas = true, + PropertyNameCaseInsensitive = true, + ReadCommentHandling = JsonCommentHandling.Skip, + UseStringEnumConverter = true)] +[JsonSerializable(typeof(ConfigData))] +internal partial class SourceGenerationContext : JsonSerializerContext { } From cdcc98e43adccd99fdee7d35feb6be54d919b078 Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Tue, 19 Nov 2024 17:02:59 +0100 Subject: [PATCH 2/7] Update readme and links to the documentation; Handle http exception due to Ollama misconfiguration --- .../AIShell.Ollama.Agent/OllamaAgent.cs | 51 +++++++++++++------ shell/agents/AIShell.Ollama.Agent/README.md | 28 +++++++--- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs index 08886226..28e421f3 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs @@ -23,7 +23,7 @@ public sealed class OllamaAgent : ILLMAgent /// /// The description of the agent to be shown at start up /// - public string Description => "This is an AI assistant to interact with a language model running locally by utilizing the Ollama CLI tool. Be sure to follow all prerequisites in aka.ms/aish/ollama"; + public string Description => "This is an AI assistant to interact with a language model running locally by utilizing the Ollama CLI tool. Be sure to follow all prerequisites in https://github.com/PowerShell/AIShell/tree/main/shell/agents/AIShell.Ollama.Agent"; /// /// This is the company added to /like and /dislike verbiage for who the telemetry helps. @@ -76,7 +76,7 @@ public void Initialize(AgentConfig config) LegalLinks = new(StringComparer.OrdinalIgnoreCase) { ["Ollama Docs"] = "https://github.com/ollama/ollama", - ["Prerequisites"] = "https://aka.ms/ollama/readme" + ["Prerequisites"] = "https://github.com/PowerShell/AIShell/tree/main/shell/agents/AIShell.Ollama.Agent" }; } @@ -125,21 +125,29 @@ public async Task ChatAsync(string input, IShell shell) if (Process.GetProcessesByName("ollama").Length is 0) { - host.RenderFullResponse("Please be sure the Ollama is installed and server is running. Check all the prerequisites in the README of this agent are met."); + host.MarkupWarningLine($"[[{Name}]]: Please be sure the Ollama is installed and server is running. Check all the prerequisites in the README of this agent are met."); return false; } - ResponseData ollamaResponse = await host.RunWithSpinnerAsync( - status: "Thinking ...", - func: async context => await _chatService.GetChatResponseAsync(context, input, token) - ).ConfigureAwait(false); + try + { + ResponseData ollamaResponse = await host.RunWithSpinnerAsync( + status: "Thinking ...", + func: async context => await _chatService.GetChatResponseAsync(context, input, token) + ).ConfigureAwait(false); - if (ollamaResponse is not null) + if (ollamaResponse is not null) + { + // render the content + host.RenderFullResponse(ollamaResponse.response); + } + } + catch (HttpRequestException) { - // render the content - host.RenderFullResponse(ollamaResponse.response); + host.MarkupWarningLine($"[[{Name}]]: Cannot serve the query due to the incorrect configuration. Please properly update the setting file."); + return false; } - + return true; } @@ -169,10 +177,23 @@ private void NewExampleSettingFile() { string SampleContent = $$""" { - // Declare Ollama model name. - "Model": "phi3", - // Declare Ollama endpoint. - "Endpoint": "http://localhost:11434/api/generate" + /* + To use Ollama API service: + + 1. Install Ollama: + winget install Ollama.Ollama + + 2. Start Ollama API server: + ollama serve + + 3. Install Ollama model: + ollama pull phi3 + */ + + // Declare Ollama model + "Model": "phi3", + // Declare Ollama endpoint + "Endpoint": "http://localhost:11434/api/generate" } """; File.WriteAllText(SettingFile, SampleContent, Encoding.UTF8); diff --git a/shell/agents/AIShell.Ollama.Agent/README.md b/shell/agents/AIShell.Ollama.Agent/README.md index 559d504a..baff9048 100644 --- a/shell/agents/AIShell.Ollama.Agent/README.md +++ b/shell/agents/AIShell.Ollama.Agent/README.md @@ -12,11 +12,29 @@ this agent you need to have Ollama installed and running. ## Configuration -Currently to change the model you will need to modify the query in the code in the -`OllamaChatService` class. The default model is `phi3`. +To configure the agent, run `/agent config ollama` to open up the setting file in your default editor, and then update the file based on the following example. -The default endpoint is `http://localhost:11434/api/generate` with `11434` being the default port. This can be changed in the code -and eventually will be added to a configuration file. +```json +{ + /* + To use Ollama API service: + + 1. Install Ollama: + winget install Ollama.Ollama + + 2. Start Ollama API server: + ollama serve + + 3. Install Ollama model: + ollama pull phi3 + */ + + // Declare Ollama model + "Model": "phi3", + // Declare Ollama endpoint + "Endpoint": "http://localhost:11434/api/generate" +} +``` ## Known Limitations @@ -24,5 +42,3 @@ and eventually will be added to a configuration file. queries - Streaming is currently not supported if you change the stream value to `true` in the data to send to the API it will not work -- Configuration is currently hard coded in the code and will be moved to a configuration file in the - future \ No newline at end of file From c0f83892b75d655ab423e765ce77c35939ecac2b Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Tue, 19 Nov 2024 17:25:52 +0100 Subject: [PATCH 3/7] Implement config file watcher to reload settings on change --- .../AIShell.Ollama.Agent/OllamaAgent.cs | 67 ++++++++++++++++++- .../AIShell.Ollama.Agent/OllamaChatService.cs | 9 +++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs index 28e421f3..7c59960e 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs @@ -7,8 +7,16 @@ namespace AIShell.Ollama.Agent; public sealed class OllamaAgent : ILLMAgent { - private const string SettingFileName = "ollama.config.json"; + private bool _reloadSettings; + private bool _isDisposed; + private string _configRoot; private Settings _settings; + private FileSystemWatcher _watcher; + + /// + /// The name of setting file + /// + private const string SettingFileName = "ollama.config.json"; /// /// Gets the settings. @@ -52,7 +60,15 @@ public sealed class OllamaAgent : ILLMAgent /// public void Dispose() { + if (_isDisposed) + { + return; + } + + GC.SuppressFinalize(this); _chatService?.Dispose(); + _watcher.Dispose(); + _isDisposed = true; } /// @@ -61,7 +77,9 @@ public void Dispose() /// Agent configuration for any configuration file and other settings public void Initialize(AgentConfig config) { - SettingFile = Path.Combine(config.ConfigurationRoot, SettingFileName); + _configRoot = config.ConfigurationRoot; + + SettingFile = Path.Combine(_configRoot, SettingFileName); _settings = ReadSettings(); if (_settings is null) @@ -73,6 +91,13 @@ public void Initialize(AgentConfig config) _chatService = new OllamaChatService(_settings); + _watcher = new FileSystemWatcher(_configRoot, SettingFileName) + { + NotifyFilter = NotifyFilters.LastWrite, + EnableRaisingEvents = true, + }; + _watcher.Changed += OnSettingFileChange; + LegalLinks = new(StringComparer.OrdinalIgnoreCase) { ["Ollama Docs"] = "https://github.com/ollama/ollama", @@ -107,7 +132,16 @@ public void OnUserAction(UserActionPayload actionPayload) {} /// Refresh the current chat by starting a new chat session. /// This method allows an agent to reset chat states, interact with user for authentication, print welcome message, and more. /// - public Task RefreshChatAsync(IShell shell, bool force) => Task.CompletedTask; + public Task RefreshChatAsync(IShell shell, bool force) + { + if (force) + { + // Reload the setting file if needed. + ReloadSettings(); + } + + return Task.CompletedTask; + } /// /// Main chat function that takes the users input and passes it to the LLM and renders it. @@ -123,6 +157,9 @@ public async Task ChatAsync(string input, IShell shell) // get the cancellation token CancellationToken token = shell.CancellationToken; + // Reload the setting file if needed. + ReloadSettings(); + if (Process.GetProcessesByName("ollama").Length is 0) { host.MarkupWarningLine($"[[{Name}]]: Please be sure the Ollama is installed and server is running. Check all the prerequisites in the README of this agent are met."); @@ -151,6 +188,22 @@ public async Task ChatAsync(string input, IShell shell) return true; } + internal void ReloadSettings() + { + if (_reloadSettings) + { + _reloadSettings = false; + var settings = ReadSettings(); + if (settings is null) + { + return; + } + + _settings = settings; + _chatService.RefreshSettings(_settings); + } + } + private Settings ReadSettings() { Settings settings = null; @@ -173,6 +226,14 @@ private Settings ReadSettings() return settings; } + private void OnSettingFileChange(object sender, FileSystemEventArgs e) + { + if (e.ChangeType is WatcherChangeTypes.Changed) + { + _reloadSettings = true; + } + } + private void NewExampleSettingFile() { string SampleContent = $$""" diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs b/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs index 63314dd7..b01a94f8 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs @@ -22,6 +22,15 @@ internal OllamaChatService(Settings settings) _client = new HttpClient(); } + /// + /// Refresh settings + /// + /// + internal void RefreshSettings(Settings settings) + { + _settings = settings; + } + /// /// Dispose of the http client /// From 0899ddbb11bd081f0ab621cec4613c23c3987986 Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Tue, 19 Nov 2024 19:15:16 +0100 Subject: [PATCH 4/7] Do not force user to specify complete endpoint URL, just IP address and port; Precise warning message --- shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs | 4 ++-- .../agents/AIShell.Ollama.Agent/OllamaChatService.cs | 2 +- shell/agents/AIShell.Ollama.Agent/README.md | 2 +- shell/agents/AIShell.Ollama.Agent/Settings.cs | 11 +++++++---- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs index 7c59960e..9fa5aa70 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs @@ -181,7 +181,7 @@ public async Task ChatAsync(string input, IShell shell) } catch (HttpRequestException) { - host.MarkupWarningLine($"[[{Name}]]: Cannot serve the query due to the incorrect configuration. Please properly update the setting file."); + host.MarkupWarningLine($"[[{Name}]]: Cannot serve the query due to the endpoint or model misconfiguration. Please properly update the setting file."); return false; } @@ -254,7 +254,7 @@ ollama pull phi3 // Declare Ollama model "Model": "phi3", // Declare Ollama endpoint - "Endpoint": "http://localhost:11434/api/generate" + "Endpoint": "http://localhost:11434" } """; File.WriteAllText(SettingFile, SampleContent, Encoding.UTF8); diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs b/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs index b01a94f8..746e5e4d 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaChatService.cs @@ -57,7 +57,7 @@ private HttpRequestMessage PrepareForChat(string input) var json = JsonSerializer.Serialize(requestData); var data = new StringContent(json, Encoding.UTF8, "application/json"); - var request = new HttpRequestMessage(HttpMethod.Post, _settings.Endpoint) { Content = data }; + var request = new HttpRequestMessage(HttpMethod.Post, $"{_settings.Endpoint}/api/generate") { Content = data }; return request; } diff --git a/shell/agents/AIShell.Ollama.Agent/README.md b/shell/agents/AIShell.Ollama.Agent/README.md index baff9048..bb7b3931 100644 --- a/shell/agents/AIShell.Ollama.Agent/README.md +++ b/shell/agents/AIShell.Ollama.Agent/README.md @@ -32,7 +32,7 @@ To configure the agent, run `/agent config ollama` to open up the setting file i // Declare Ollama model "Model": "phi3", // Declare Ollama endpoint - "Endpoint": "http://localhost:11434/api/generate" + "Endpoint": "http://localhost:11434" } ``` diff --git a/shell/agents/AIShell.Ollama.Agent/Settings.cs b/shell/agents/AIShell.Ollama.Agent/Settings.cs index 7ac3555b..fc6bcb28 100644 --- a/shell/agents/AIShell.Ollama.Agent/Settings.cs +++ b/shell/agents/AIShell.Ollama.Agent/Settings.cs @@ -5,13 +5,16 @@ namespace AIShell.Ollama.Agent; internal class Settings { - public string Model { get; set; } - public string Endpoint { get; set; } + private string _model; + private string _endpoint; + + public string Model => _model; + public string Endpoint => _endpoint; public Settings(ConfigData configData) { - Model = configData.Model; - Endpoint = configData.Endpoint; + _model = configData?.Model; + _endpoint = configData?.Endpoint.TrimEnd('/'); } } From bcc5d1e3e23b8995a7f45629667dad89381cbe33 Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Tue, 19 Nov 2024 19:17:52 +0100 Subject: [PATCH 5/7] Change json to config so comments are not rendered on GitHub in red --- shell/agents/AIShell.Ollama.Agent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/agents/AIShell.Ollama.Agent/README.md b/shell/agents/AIShell.Ollama.Agent/README.md index bb7b3931..2401b645 100644 --- a/shell/agents/AIShell.Ollama.Agent/README.md +++ b/shell/agents/AIShell.Ollama.Agent/README.md @@ -14,7 +14,7 @@ this agent you need to have Ollama installed and running. To configure the agent, run `/agent config ollama` to open up the setting file in your default editor, and then update the file based on the following example. -```json +```config { /* To use Ollama API service: From 9c358b861c4d94088e24498440617492d226702a Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Tue, 19 Nov 2024 19:32:49 +0100 Subject: [PATCH 6/7] Revert to json and update the comments in the config file --- .../AIShell.Ollama.Agent/OllamaAgent.cs | 19 ++++------ shell/agents/AIShell.Ollama.Agent/README.md | 36 ++++++++----------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs index 9fa5aa70..3ac2aa7c 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs @@ -238,18 +238,13 @@ private void NewExampleSettingFile() { string SampleContent = $$""" { - /* - To use Ollama API service: - - 1. Install Ollama: - winget install Ollama.Ollama - - 2. Start Ollama API server: - ollama serve - - 3. Install Ollama model: - ollama pull phi3 - */ + // To use Ollama API service: + // 1. Install Ollama: + // winget install Ollama.Ollama + // 2. Start Ollama API server: + // ollama serve + // 3. Install Ollama model: + // ollama pull phi3 // Declare Ollama model "Model": "phi3", diff --git a/shell/agents/AIShell.Ollama.Agent/README.md b/shell/agents/AIShell.Ollama.Agent/README.md index 2401b645..87375aec 100644 --- a/shell/agents/AIShell.Ollama.Agent/README.md +++ b/shell/agents/AIShell.Ollama.Agent/README.md @@ -5,34 +5,28 @@ this agent you need to have Ollama installed and running. ## Pre-requisites to using the agent -- Install [Ollama](https://github.com/ollama/ollama) -- Install a [Ollama model](https://github.com/ollama/ollama?tab=readme-ov-file#model-library), we - suggest using the `phi3` model as it is set as the default model in the code +- Install [Ollama](https://github.com/ollama/ollama) +- Install a [Ollama model](https://github.com/ollama/ollama?tab=readme-ov-file#model-library), we suggest using the `phi3` model as it is set as the default model in the code - [Start the Ollama API server](https://github.com/ollama/ollama?tab=readme-ov-file#start-ollama) ## Configuration To configure the agent, run `/agent config ollama` to open up the setting file in your default editor, and then update the file based on the following example. -```config +```json { - /* - To use Ollama API service: - - 1. Install Ollama: - winget install Ollama.Ollama - - 2. Start Ollama API server: - ollama serve - - 3. Install Ollama model: - ollama pull phi3 - */ - - // Declare Ollama model - "Model": "phi3", - // Declare Ollama endpoint - "Endpoint": "http://localhost:11434" + // To use Ollama API service: + // 1. Install Ollama: + // winget install Ollama.Ollama + // 2. Start Ollama API server: + // ollama serve + // 3. Install Ollama model: + // ollama pull phi3 + + // Declare Ollama model + "Model": "phi3", + // Declare Ollama endpoint + "Endpoint": "http://localhost:11434" } ``` From 9b57754a1e7cedd8682a8dd2d1bc011b6e126203 Mon Sep 17 00:00:00 2001 From: Kris Borowinski Date: Wed, 20 Nov 2024 17:03:29 +0100 Subject: [PATCH 7/7] Add model and endpoint self check; Change warnings to errors; Fix possible null exception --- .../AIShell.Ollama.Agent/OllamaAgent.cs | 27 ++++++++++++++++++- shell/agents/AIShell.Ollama.Agent/Settings.cs | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs index 3ac2aa7c..d3a4dcba 100644 --- a/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs +++ b/shell/agents/AIShell.Ollama.Agent/OllamaAgent.cs @@ -166,6 +166,11 @@ public async Task ChatAsync(string input, IShell shell) return false; } + if (!SelfCheck(host)) + { + return false; + } + try { ResponseData ollamaResponse = await host.RunWithSpinnerAsync( @@ -181,7 +186,7 @@ public async Task ChatAsync(string input, IShell shell) } catch (HttpRequestException) { - host.MarkupWarningLine($"[[{Name}]]: Cannot serve the query due to the endpoint or model misconfiguration. Please properly update the setting file."); + host.WriteErrorLine($"[{Name}]: Cannot serve the query due to the Endpoint or Model misconfiguration. Please properly update the setting file."); return false; } @@ -234,6 +239,26 @@ private void OnSettingFileChange(object sender, FileSystemEventArgs e) } } + internal bool SelfCheck(IHost host) + { + var settings = new (string settingValue, string settingName)[] + { + (_settings?.Model, "Model"), + (_settings?.Endpoint, "Endpoint") + }; + + foreach (var (settingValue, settingName) in settings) + { + if (string.IsNullOrWhiteSpace(settingValue)) + { + host.WriteErrorLine($"[{Name}]: {settingName} is undefined. Please declare it in the setting file."); + return false; + } + } + + return true; + } + private void NewExampleSettingFile() { string SampleContent = $$""" diff --git a/shell/agents/AIShell.Ollama.Agent/Settings.cs b/shell/agents/AIShell.Ollama.Agent/Settings.cs index fc6bcb28..ad7dccef 100644 --- a/shell/agents/AIShell.Ollama.Agent/Settings.cs +++ b/shell/agents/AIShell.Ollama.Agent/Settings.cs @@ -14,7 +14,7 @@ internal class Settings public Settings(ConfigData configData) { _model = configData?.Model; - _endpoint = configData?.Endpoint.TrimEnd('/'); + _endpoint = configData?.Endpoint?.TrimEnd('/'); } }