Skip to content

Add support for --agent parameter to allow non-interactive agent selection #386

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,14 @@ Agent README files:
- [`interpreter`][07]
- [`azure`][17] (shipped with AI Shell)

When you run `aish`, you are prompted to choose an agent. For more details about each agent, see the
README in the each agent folder.
When you run `aish`, you are prompted to choose an agent. You can also specify an agent directly using the `--agent` or `-a` parameter:

```bash
aish --agent openai-gpt
aish -a azure
```

For more details about each agent, see the README in the each agent folder.

To learn more about how to create an agent for yourself please see, [Creating an Agent][03].

Expand Down Expand Up @@ -120,9 +126,18 @@ key bindings will be supported in future releases.

### Configuration

Currently, AI Shell supports very basic configuration. One can creates a file named `config.json`
under `~/.aish` to configure AI Shell, but it only supports declaring the default agent to use at
startup. This way you do not need to select agents every time you run `aish.exe`
Currently, AI Shell supports very basic configuration. You can specify which agent to use in several ways:

1. **Command line parameter** (highest priority): `aish --agent openai-gpt` or `aish -a azure`
2. **Configuration file**: Create a file named `config.json` under `~/.aish` to declare the default agent:

```json
{
"DefaultAgent": "openai-gpt"
}
```

This way you do not need to select agents every time you run `aish.exe`

Configuration of AI Shell will be improved in future releases to support custom key bindings, color
themes and more.
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "8.0.409"
"version": "8.0.116"
}
}
9 changes: 5 additions & 4 deletions shell/AIShell.App/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static int Main(string[] args)
Argument<string> query = new("query", getDefaultValue: () => null, "The query term used to get response from AI.");
Option<string> channel = new("--channel", "A named pipe used to setup communication between aish and the command-line shell.");
Option<FileInfo> shellWrapper = new("--shell-wrapper", "Path to the configuration file to wrap AIShell as a different application.");
Option<string> agent = new(["--agent", "-a"], "The AI agent to use for this session.");

query.AddValidator(result =>
{
Expand All @@ -38,20 +39,20 @@ static int Main(string[] args)
}
});

RootCommand rootCommand = new("AI for the command line.") { query, channel, shellWrapper };
rootCommand.SetHandler(StartShellAsync, query, channel, shellWrapper);
RootCommand rootCommand = new("AI for the command line.") { query, channel, shellWrapper, agent };
rootCommand.SetHandler(StartShellAsync, query, channel, shellWrapper, agent);
return rootCommand.Invoke(args);
}

private async static Task StartShellAsync(string query, string channel, FileInfo shellWrapperConfigFile)
private async static Task StartShellAsync(string query, string channel, FileInfo shellWrapperConfigFile, string agent)
{
if (!ReadShellWrapperConfig(shellWrapperConfigFile, out ShellWrapper shellWrapper))
{
return;
}

Utils.Setup(shellWrapper?.Name);
ShellArgs args = new(shellWrapper, channel);
ShellArgs args = new(shellWrapper, channel, agent);

Shell shell;
if (query is not null)
Expand Down
8 changes: 6 additions & 2 deletions shell/AIShell.Kernel/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal sealed class Shell : IShell
private readonly ShellWrapper _wrapper;
private readonly HashSet<string> _textToIgnore;
private readonly Setting _setting;
private readonly string _commandLineAgent;

private bool _shouldRefresh;
private LLMAgent _activeAgent;
Expand Down Expand Up @@ -90,6 +91,7 @@ internal Shell(bool interactive, ShellArgs args)
{
_isInteractive = interactive;
_wrapper = args.ShellWrapper;
_commandLineAgent = args.Agent;

// Create the channel if the args is specified.
// The channel object starts the connection initialization on a background thread,
Expand Down Expand Up @@ -261,7 +263,7 @@ private void LoadAvailableAgents()
try
{
LLMAgent chosenAgent = null;
string active = _wrapper?.Agent ?? _setting.DefaultAgent;
string active = _commandLineAgent ?? _wrapper?.Agent ?? _setting.DefaultAgent;
if (!string.IsNullOrEmpty(active))
{
foreach (LLMAgent agent in _agents)
Expand All @@ -275,7 +277,9 @@ private void LoadAvailableAgents()

if (chosenAgent is null)
{
Host.MarkupWarningLine($"The configured active agent '{active}' is not available.\n");
string source = !string.IsNullOrEmpty(_commandLineAgent) ? "command line" :
!string.IsNullOrEmpty(_wrapper?.Agent) ? "wrapper configuration" : "default configuration";
Host.MarkupWarningLine($"The {source} agent '{active}' is not available.\n");
}
else if (_wrapper?.Prompt is not null)
{
Expand Down
7 changes: 6 additions & 1 deletion shell/AIShell.Kernel/Utility/ShellArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace AIShell.Kernel;
/// <summary>
/// Arguments for the AI shell.
/// </summary>
public sealed class ShellArgs(ShellWrapper shellWrapper, string channel)
public sealed class ShellArgs(ShellWrapper shellWrapper, string channel, string agent)
{
/// <summary>
/// Gets the named pipe used to setup communication between aish and the command-line shell.
Expand All @@ -16,4 +16,9 @@ public sealed class ShellArgs(ShellWrapper shellWrapper, string channel)
/// Gets the shell wrapper configuration.
/// </summary>
public ShellWrapper ShellWrapper { get; } = shellWrapper;

/// <summary>
/// Gets the AI agent name to use for this session.
/// </summary>
public string Agent { get; } = string.IsNullOrEmpty(agent) ? null : agent;
}