diff --git a/shell/AIShell.Abstraction/IShell.cs b/shell/AIShell.Abstraction/IShell.cs
index bd638465..8b1ab7dd 100644
--- a/shell/AIShell.Abstraction/IShell.cs
+++ b/shell/AIShell.Abstraction/IShell.cs
@@ -10,6 +10,11 @@ public interface IShell
///
IHost Host { get; }
+ ///
+ /// Indicates whether the bi-directional channel with an application (e.g. a PowerShell session) has been established.
+ ///
+ bool ChannelEstablished { get; }
+
///
/// The token to indicate cancellation when `Ctrl+c` is pressed by user.
///
diff --git a/shell/AIShell.Kernel/Shell.cs b/shell/AIShell.Kernel/Shell.cs
index c646d2e5..48424e8c 100644
--- a/shell/AIShell.Kernel/Shell.cs
+++ b/shell/AIShell.Kernel/Shell.cs
@@ -77,6 +77,7 @@ internal sealed class Shell : IShell
#region IShell implementation
IHost IShell.Host => Host;
+ bool IShell.ChannelEstablished => Channel is not null;
CancellationToken IShell.CancellationToken => _cancellationSource.Token;
List IShell.ExtractCodeBlocks(string text, out List sourceInfos) => Utils.ExtractCodeBlocks(text, out sourceInfos);
diff --git a/shell/agents/Microsoft.Azure.Agent/AzureAgent.cs b/shell/agents/Microsoft.Azure.Agent/AzureAgent.cs
index 1b18f66a..3ccb764b 100644
--- a/shell/agents/Microsoft.Azure.Agent/AzureAgent.cs
+++ b/shell/agents/Microsoft.Azure.Agent/AzureAgent.cs
@@ -265,7 +265,7 @@ public async Task ChatAsync(string input, IShell shell)
ArgPlaceholder = new ArgumentPlaceholder(input, data, _httpClient);
}
- string answer = data is null ? _copilotResponse.Text : GenerateAnswer(data);
+ string answer = data is null ? _copilotResponse.Text : GenerateAnswer(data, shell);
host.RenderFullResponse(answer);
}
}
@@ -503,8 +503,13 @@ internal void ReplaceKnownPlaceholders(ResponseData data)
}
}
- internal string GenerateAnswer(ResponseData data)
+ internal string GenerateAnswer(ResponseData data, IShell shell)
{
+ // Use green (0,195,0) on grey (48,48,48) for rendering commands in the markdown.
+ // TODO: the color formatting should be exposed by the shell as utility method.
+ const string CommandVTColor = "\x1b[38;2;0;195;0;48;2;48;48;48m";
+ const string ResetVT = "\x1b[0m";
+
_buffer.Clear();
string text = data.Text;
@@ -528,7 +533,13 @@ internal string GenerateAnswer(ResponseData data)
_buffer.Append(text.AsSpan(index, text.Length - index));
}
- if (data.PlaceholderSet is not null)
+ if (data.PlaceholderSet is null)
+ {
+ _buffer.Append(shell.ChannelEstablished
+ ? $"\nRun {CommandVTColor} /code post {ResetVT} or press {CommandVTColor} Ctrl+d,Ctrl+d {ResetVT} to post the code to the connected shell.\n"
+ : $"\nRun {CommandVTColor} /code copy {ResetVT} or press {CommandVTColor} Ctrl+d,Ctrl+c {ResetVT} to copy the code to clipboard.\n");
+ }
+ else
{
// Construct text about the placeholders if we successfully stripped the placeholder
// section off from the original response.
@@ -547,7 +558,7 @@ internal string GenerateAnswer(ResponseData data)
// 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");
+ _buffer.Append($"\nRun {CommandVTColor} /replace {ResetVT} to get assistance in placeholder replacement.\n");
}
}
diff --git a/shell/agents/Microsoft.Azure.Agent/Command.cs b/shell/agents/Microsoft.Azure.Agent/Command.cs
index 10522d0e..a394d4bc 100644
--- a/shell/agents/Microsoft.Azure.Agent/Command.cs
+++ b/shell/agents/Microsoft.Azure.Agent/Command.cs
@@ -254,6 +254,6 @@ private async Task RegenerateAsync()
_agent.ResetArgumentPlaceholder();
}
- return _agent.GenerateAnswer(data);
+ return _agent.GenerateAnswer(data, Shell);
}
}
diff --git a/shell/shell.common.props b/shell/shell.common.props
index 7e98aa6a..55ca1778 100644
--- a/shell/shell.common.props
+++ b/shell/shell.common.props
@@ -8,7 +8,7 @@
net8.0
enable
12.0
- 0.1.0-alpha.19
+ 0.1.0-alpha.20
true
true