Skip to content
Merged
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
2 changes: 1 addition & 1 deletion shell/AIShell.Abstraction/ILLMAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public interface ILLMAgent : IDisposable

/// <summary>
/// Refresh the current chat or force starting a new chat session.
/// This method allows an agent to reset chat states, interact with user for authentication, print welcome message, and more.
/// This method allows an agent to reset chat states, refresh token or settings, interact with user for authentication, print welcome message, and more.
/// </summary>
/// <param name="shell">The interface for interacting with the shell.</param>
/// <param name="force">Whether or not to force creating a new chat session.</param>
Expand Down
2 changes: 1 addition & 1 deletion shell/AIShell.Kernel/LLMAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal LLMAgent(ILLMAgent agent, AgentAssemblyLoadContext loadContext)
{
Impl = agent;
LoadContext = loadContext;
Prompt = agent.Name;
Prompt = $"@{agent.Name}";
}

internal void Display(Host host, string description = null)
Expand Down
26 changes: 20 additions & 6 deletions shell/AIShell.Kernel/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ private void LoadAvailableAgents()
chosenAgent ??= _agents.Count is 1
? _agents[0]
: Host.PromptForSelectionAsync(
title: "[orange1]Please select an [Blue]agent[/] to use[/]:",
title: "[orange1]Please select an [Blue]agent[/] to use[/]:\n[grey](You can switch to another agent later by typing [Blue]@<agent name>[/])[/]",
choices: _agents,
converter: static a => a.Impl.Name)
.GetAwaiter().GetResult();
Expand Down Expand Up @@ -538,6 +538,18 @@ private async Task<string> ReadUserInput(string prompt, CancellationToken cancel
return input;
}

/// <summary>
/// Give an agent the opportunity to refresh its chat session, in the unforced way.
/// </summary>
private async Task RefreshChatAsNeeded(LLMAgent agent)
{
if (_shouldRefresh)
{
_shouldRefresh = false;
await agent?.Impl.RefreshChatAsync(this, force: false);
}
}

/// <summary>
/// Run a chat REPL.
/// </summary>
Expand All @@ -552,11 +564,7 @@ internal async Task RunREPLAsync()

try
{
if (_shouldRefresh)
{
_shouldRefresh = false;
await agent?.Impl.RefreshChatAsync(this, force: false);
}
await RefreshChatAsNeeded(agent);

if (Regenerate)
{
Expand Down Expand Up @@ -595,6 +603,12 @@ internal async Task RunREPLAsync()
{
continue;
}
else
{
// We may be switching to an agent that hasn't setup its chat session yet.
// So, give it a chance to do so before calling its 'Chat' method.
await RefreshChatAsNeeded(agent);
}
}

string copiedText = await GetClipboardContent(input);
Expand Down
15 changes: 9 additions & 6 deletions shell/agents/AIShell.Interpreter.Agent/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,15 @@ public void Initialize(AgentConfig config)
/// <inheritdoc/>
public Task RefreshChatAsync(IShell shell, bool force)
{
// Reload the setting file if needed.
ReloadSettings();
// Reset the history so the subsequent chat can start fresh.
_chatService.RefreshChat();
// Shut down the execution service to start fresh.
_executionService.Terminate();
if (force)
{
// Reload the setting file if needed.
ReloadSettings();
// Reset the history so the subsequent chat can start fresh.
_chatService.RefreshChat();
// Shut down the execution service to start fresh.
_executionService.Terminate();
}

return Task.CompletedTask;
}
Expand Down
11 changes: 7 additions & 4 deletions shell/agents/AIShell.OpenAI.Agent/Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ public void OnUserAction(UserActionPayload actionPayload) {}
/// <inheritdoc/>
public Task RefreshChatAsync(IShell shell, bool force)
{
// Reload the setting file if needed.
ReloadSettings();
// Reset the history so the subsequent chat can start fresh.
_chatService.ChatHistory.Clear();
if (force)
{
// Reload the setting file if needed.
ReloadSettings();
// Reset the history so the subsequent chat can start fresh.
_chatService.ChatHistory.Clear();
}

return Task.CompletedTask;
}
Expand Down
16 changes: 12 additions & 4 deletions shell/agents/Microsoft.Azure.Agent/AzureAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public AzureAgent()

public void Dispose()
{
ArgPlaceholder?.DataRetriever?.Dispose();
ResetArgumentPlaceholder();
_chatSession.Dispose();
_httpClient.Dispose();

Expand Down Expand Up @@ -120,6 +120,7 @@ public async Task RefreshChatAsync(IShell shell, bool force)
{
IHost host = shell.Host;
CancellationToken cancellationToken = shell.CancellationToken;
ResetArgumentPlaceholder();

try
{
Expand Down Expand Up @@ -179,8 +180,7 @@ public async Task<bool> ChatAsync(string input, IShell shell)

if (_copilotResponse.ChunkReader is null)
{
ArgPlaceholder?.DataRetriever?.Dispose();
ArgPlaceholder = null;
ResetArgumentPlaceholder();

// Process CLI handler response specially to support parameter injection.
ResponseData data = null;
Expand Down Expand Up @@ -360,6 +360,12 @@ private ResponseData ParseCLIHandlerResponse(IShell shell)
return data;
}

internal void ResetArgumentPlaceholder()
{
ArgPlaceholder?.DataRetriever?.Dispose();
ArgPlaceholder = null;
}

internal void SaveUserValue(string phName, string value)
{
ArgumentException.ThrowIfNullOrEmpty(phName);
Expand Down Expand Up @@ -465,7 +471,9 @@ internal string GenerateAnswer(ResponseData data)
_buffer.Append($"- `{phItem.Name}`: {phItem.Desc}\n");
}

_buffer.Append("\nRun `/replace` to get assistance in placeholder replacement.\n");
// Use green (0,195,0) on grey (48,48,48) for rendering the command '/replace'.
// TODO: the color formatting should be exposed by the shell as utility method.
_buffer.Append("\nRun \x1b[38;2;0;195;0;48;2;48;48;48m /replace \x1b[0m to get assistance in placeholder replacement.\n");
}
}

Expand Down
4 changes: 2 additions & 2 deletions shell/agents/Microsoft.Azure.Agent/ChatSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ internal async Task<string> RefreshAsync(IStatusContext context, bool force, Can
if (force)
{
// End the existing conversation.
context.Status("End current chat ...");
context.Status("Ending current chat ...");
EndConversation();
Reset();
}
else
{
try
{
context.Status("Refresh DirectLine token ...");
context.Status("Refreshing token ...");
await RenewTokenAsync(cancellationToken);
return null;
}
Expand Down
3 changes: 1 addition & 2 deletions shell/agents/Microsoft.Azure.Agent/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,7 @@ private async Task<string> RegenerateAsync()

if (data.PlaceholderSet is null)
{
_agent.ArgPlaceholder.DataRetriever.Dispose();
_agent.ArgPlaceholder = null;
_agent.ResetArgumentPlaceholder();
}

return _agent.GenerateAnswer(data);
Expand Down