-
Notifications
You must be signed in to change notification settings - Fork 51
Enhanced Model Management and SystemPrompt Integration in OllamaAgent #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
daxian-dbw
merged 15 commits into
PowerShell:main
from
cnupy:ollama-multy-model-support
Apr 25, 2025
Merged
Changes from 2 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
2b67582
OllamaAgent can now handle and switch between multiple models seamles…
cnupy 2d96206
Fix indentation in the error message when handling HttpRequestException
cnupy a3b4a22
Refactor model handling in OllamaAgent to simplify model retrieval an…
cnupy 4279c88
Merge branch 'PowerShell:main' into ollama-multy-model-support
cnupy c18b187
Remove redundant parameter from UseConfg method in ConfigCommand
cnupy 3d95100
Merge branch 'ollama-multy-model-support' of github.com:cnupy/AIShell…
cnupy 1990232
Update shell/agents/AIShell.Ollama.Agent/Settings.cs
cnupy 153970a
Refactor model handling in ConfigCommand and Settings classes for imp…
cnupy 9d1998f
Rename ConfigCommand to PresetCommand and update related methods for …
cnupy 6d66786
Rename "Configs" to "Presets" and update related comments in OllamaAg…
cnupy 51a611e
Some refactoring and updates
daxian-dbw c9f549e
Update the readme doc
daxian-dbw db22595
A little cleanup
daxian-dbw ed5fb44
Add more comments and make some additional updates
daxian-dbw 2cefb83
Update comments
daxian-dbw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,280 @@ | ||
using System.CommandLine; | ||
using System.CommandLine.Completions; | ||
using System.Threading.Tasks; | ||
using AIShell.Abstraction; | ||
|
||
namespace AIShell.Ollama.Agent; | ||
|
||
internal sealed class ConfigCommand : CommandBase | ||
{ | ||
private readonly OllamaAgent _agnet; | ||
public ConfigCommand(OllamaAgent agent) | ||
: base("config", "Command for config management within the 'ollama' agent.") | ||
{ | ||
_agnet = agent; | ||
|
||
var use = new Command("use", "Specify a config to use."); | ||
var useConfig = new Argument<string>( | ||
name: "Config", | ||
getDefaultValue: () => null, | ||
description: "Name of a configuration.").AddCompletions(ConfigNameCompleter); | ||
use.AddArgument(useConfig); | ||
use.SetHandler(UseConfigAction, useConfig); | ||
|
||
var list = new Command("list", "List a specific config, or all available configs."); | ||
var listConfig = new Argument<string>( | ||
name: "Config", | ||
getDefaultValue: () => null, | ||
description: "Name of a configuration.").AddCompletions(ConfigNameCompleter); | ||
list.AddArgument(listConfig); | ||
list.SetHandler(ListConfigAction, listConfig); | ||
|
||
AddCommand(list); | ||
AddCommand(use); | ||
} | ||
|
||
private void ListConfigAction(string name) | ||
{ | ||
IHost host = Shell.Host; | ||
|
||
// Reload the setting file if needed. | ||
_agnet.ReloadSettings(); | ||
|
||
Settings settings = _agnet.Settings; | ||
|
||
if (settings is null) | ||
{ | ||
host.WriteErrorLine("Invalid configuration."); | ||
return; | ||
} | ||
|
||
if (string.IsNullOrEmpty(name)) | ||
{ | ||
settings.ListAllConfigs(host); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
settings.ShowOneConfig(host, name); | ||
} | ||
catch (InvalidOperationException ex) | ||
{ | ||
string availableConfigNames = ConfigNamesAsString(); | ||
host.WriteErrorLine($"{ex.Message} Available cofiguration(s): {availableConfigNames}."); | ||
} | ||
} | ||
|
||
private async Task UseConfigAction(string name) | ||
{ | ||
// Reload the setting file if needed. | ||
_agnet.ReloadSettings(); | ||
|
||
var setting = _agnet.Settings; | ||
var host = Shell.Host; | ||
|
||
if (setting is null || setting.Configs.Count is 0) | ||
{ | ||
host.WriteErrorLine("No configs configured."); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
ModelConfig chosenConfig = (string.IsNullOrEmpty(name) | ||
? host.PromptForSelectionAsync( | ||
title: "[orange1]Please select a [Blue]Configuration[/] to use[/]:", | ||
choices: setting.Configs, | ||
converter: ConfigName, | ||
CancellationToken.None).GetAwaiter().GetResult() | ||
: setting.Configs.FirstOrDefault(c => c.Name == name)) ?? throw new InvalidOperationException($"The configuration '{name}' doesn't exist."); | ||
await setting.UseConfg(host, chosenConfig); | ||
host.MarkupLine($"Using the config [green]{chosenConfig.Name}[/]:"); | ||
} | ||
catch (InvalidOperationException ex) | ||
{ | ||
string availableConfigNames = ConfigNamesAsString(); | ||
host.WriteErrorLine($"{ex.Message} Available configurations: {availableConfigNames}."); | ||
} | ||
} | ||
|
||
private static string ConfigName(ModelConfig config) => config.Name.Any(Char.IsWhiteSpace) ? $"\"{config.Name}\"" : config.Name; | ||
private IEnumerable<string> ConfigNameCompleter(CompletionContext context) => _agnet.Settings?.Configs?.Select(ConfigName) ?? []; | ||
private string ConfigNamesAsString() => string.Join(", ", ConfigNameCompleter(null)); | ||
} | ||
|
||
internal sealed class SystemPromptCommand : CommandBase | ||
{ | ||
private readonly OllamaAgent _agnet; | ||
|
||
public SystemPromptCommand(OllamaAgent agent) | ||
: base("system-prompt", "Command for system prompt management within the 'ollama' agent.") | ||
{ | ||
_agnet = agent; | ||
|
||
var show = new Command("show", "Show the current system prompt."); | ||
show.SetHandler(ShowSystemPromptAction); | ||
|
||
var set = new Command("set", "Sets the system prompt."); | ||
var systemPromptModel = new Argument<string>( | ||
name: "System-Prompt", | ||
getDefaultValue: () => null, | ||
description: "The system prompt"); | ||
set.AddArgument(systemPromptModel); | ||
set.SetHandler(SetSystemPromptAction, systemPromptModel); | ||
|
||
AddCommand(show); | ||
AddCommand(set); | ||
} | ||
|
||
private void ShowSystemPromptAction() | ||
{ | ||
IHost host = Shell.Host; | ||
|
||
// Reload the setting file if needed. | ||
_agnet.ReloadSettings(); | ||
|
||
Settings settings = _agnet.Settings; | ||
|
||
if (settings is null) | ||
{ | ||
host.WriteErrorLine("Invalid configuration."); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
settings.ShowSystemPrompt(host); | ||
} | ||
catch (InvalidOperationException ex) | ||
{ | ||
host.WriteErrorLine($"{ex.Message}"); | ||
} | ||
} | ||
|
||
private void SetSystemPromptAction(string prompt) | ||
{ | ||
IHost host = Shell.Host; | ||
|
||
// Reload the setting file if needed. | ||
_agnet.ReloadSettings(); | ||
_agnet.ResetContext(); | ||
|
||
Settings settings = _agnet.Settings; | ||
|
||
if (settings is null) | ||
{ | ||
host.WriteErrorLine("Invalid configuration."); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
settings.SetSystemPrompt(host, prompt); | ||
} | ||
catch (InvalidOperationException ex) | ||
{ | ||
host.WriteErrorLine($"{ex.Message}."); | ||
} | ||
} | ||
} | ||
|
||
internal sealed class ModelCommand : CommandBase | ||
daxian-dbw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
private readonly OllamaAgent _agnet; | ||
|
||
public ModelCommand(OllamaAgent agent) | ||
: base("model", "Command for model management within the 'ollama' agent.") | ||
{ | ||
_agnet = agent; | ||
|
||
var use = new Command("use", "Specify a model to use, or choose one from the available models."); | ||
var useModel = new Argument<string>( | ||
name: "Model", | ||
getDefaultValue: () => null, | ||
description: "Name of a model.").AddCompletions(ModelNameCompleter); | ||
use.AddArgument(useModel); | ||
use.SetHandler(UseModelAction, useModel); | ||
|
||
var list = new Command("list", "List a specific model, or all available models."); | ||
var listModel = new Argument<string>( | ||
name: "Model", | ||
getDefaultValue: () => null, | ||
description: "Name of a model.").AddCompletions(ModelNameCompleter); | ||
list.AddArgument(listModel); | ||
list.SetHandler(ListModelAction, listModel); | ||
|
||
AddCommand(list); | ||
AddCommand(use); | ||
} | ||
|
||
private void ListModelAction(string name) | ||
{ | ||
IHost host = Shell.Host; | ||
|
||
// Reload the setting file if needed. | ||
_agnet.ReloadSettings(); | ||
|
||
Settings settings = _agnet.Settings; | ||
|
||
if (settings is null) | ||
{ | ||
host.WriteErrorLine("Invalid configuration."); | ||
return; | ||
} | ||
|
||
if (string.IsNullOrEmpty(name)) | ||
{ | ||
settings.ListAllModels(host).GetAwaiter().GetResult(); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
settings.ShowOneModel(host, name).GetAwaiter().GetResult(); | ||
} | ||
catch (InvalidOperationException ex) | ||
{ | ||
string availableModelNames = ModelNamesAsString(); | ||
host.WriteErrorLine($"{ex.Message} Available Models(s): {availableModelNames}."); | ||
} | ||
} | ||
|
||
private void UseModelAction(string name) | ||
{ | ||
// Reload the setting file if needed. | ||
_agnet.ReloadSettings(); | ||
|
||
var setting = _agnet.Settings; | ||
var host = Shell.Host; | ||
|
||
if (setting is null || setting.GetAllModels().GetAwaiter().GetResult().Count is 0) | ||
{ | ||
host.WriteErrorLine("No models configured."); | ||
return; | ||
} | ||
|
||
try | ||
{ | ||
OllamaModel chosenModel = string.IsNullOrEmpty(name) | ||
? host.PromptForSelectionAsync( | ||
title: "[orange1]Please select a [Blue]Model[/] to use[/]:", | ||
choices: setting.GetAllModels().GetAwaiter().GetResult(), | ||
converter: ModelName, | ||
CancellationToken.None).GetAwaiter().GetResult() | ||
: setting.GetModelByName(name).GetAwaiter().GetResult(); | ||
|
||
setting.UseModel(chosenModel); | ||
host.MarkupLine($"Using the model [green]{chosenModel.Name}[/]:"); | ||
} | ||
catch (InvalidOperationException ex) | ||
{ | ||
string availableModelNames = ModelNamesAsString(); | ||
host.WriteErrorLine($"{ex.Message} Available Modless: {availableModelNames}."); | ||
} | ||
} | ||
|
||
private static string ModelName(OllamaModel model) => model.Name; | ||
private IEnumerable<string> ModelNameCompleter(CompletionContext context) => _agnet.Settings?.GetAllModels().GetAwaiter().GetResult().Select(ModelName) ?? []; | ||
private string ModelNamesAsString() => string.Join(", ", ModelNameCompleter(null)); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.