Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 [Blue]@[/] tagging its 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