Skip to content

Commit d439a3e

Browse files
authored
Make the dynamic argument value retrieval cross-platform (#274)
- Make the dynamic argument value retrieval cross-platform - Update the authentication status messages to not show the `DirectLine` token request.
1 parent 896077a commit d439a3e

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

shell/agents/Microsoft.Azure.Agent/ChatSession.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,8 @@ private async Task<string> SetupNewChat(IStatusContext context, CancellationToke
124124
context.Status("Check Copilot authorization ...");
125125
await CheckAuthorizationAsync(cancellationToken);
126126

127-
context.Status("Request for DirectLine token ...");
128-
await GetInitialDLTokenAsync(cancellationToken);
129-
130127
context.Status("Start a new chat session ...");
128+
await GetInitialDLTokenAsync(cancellationToken);
131129
return await OpenConversationAsync(cancellationToken);
132130
}
133131
catch (Exception e)

shell/agents/Microsoft.Azure.Agent/DataRetriever.cs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal class DataRetriever : IDisposable
1515
private const string MetadataQueryTemplate = "{{\"command\":\"{0}\"}}";
1616
private const string MetadataEndpoint = "https://cli-validation-tool-meta-qry.azurewebsites.net/api/command_metadata";
1717

18-
private static string s_azPythonPath;
18+
private static readonly string s_azCompleteCmd, s_azCompleteArg;
1919
private static readonly Dictionary<string, NamingRule> s_azNamingRules;
2020
private static readonly ConcurrentDictionary<string, AzCLICommand> s_azStaticDataCache;
2121

@@ -306,26 +306,45 @@ static DataRetriever()
306306
s_azNamingRules.Add(rule.AzPSCommand, rule);
307307
}
308308

309-
s_azPythonPath = GetAzCLIPythonPath();
309+
(s_azCompleteCmd, s_azCompleteArg) = GetAzCLIPythonPath();
310310
s_azStaticDataCache = new(StringComparer.OrdinalIgnoreCase);
311311
}
312312

313313
/// <summary>
314314
/// TODO: Need to support Linux and macOS.
315315
/// </summary>
316-
private static string GetAzCLIPythonPath()
316+
private static (string compCmd, string compArg) GetAzCLIPythonPath()
317317
{
318318
if (OperatingSystem.IsWindows())
319319
{
320-
const string AzWindowsPath = @"Microsoft SDKs\Azure\CLI2\python.exe";
321-
string x64Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), AzWindowsPath);
322-
string x86Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), AzWindowsPath);
320+
const string AzWinCmd = @"Microsoft SDKs\Azure\CLI2\python.exe";
321+
const string AzWinArg = "-Im azure.cli";
323322

324-
if (File.Exists(x64Path)) { return x64Path; }
325-
if (File.Exists(x86Path)) { return x86Path; }
323+
string x64Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), AzWinCmd);
324+
string x86Path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), AzWinCmd);
325+
326+
if (File.Exists(x64Path)) { return (x64Path, AzWinArg); }
327+
if (File.Exists(x86Path)) { return (x86Path, AzWinArg); }
328+
}
329+
else
330+
{
331+
// On Linux and macOS, simply run 'az' as starting a new process is cheap.
332+
string pathEnv = Environment.GetEnvironmentVariable("PATH");
333+
if (!string.IsNullOrEmpty(pathEnv))
334+
{
335+
string[] paths = pathEnv.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries);
336+
foreach (string path in paths)
337+
{
338+
string fullPath = Path.Combine(path, "az");
339+
if (File.Exists(fullPath))
340+
{
341+
return (fullPath, string.Empty);
342+
}
343+
}
344+
}
326345
}
327346

328-
return null;
347+
return (null, null);
329348
}
330349

331350
internal DataRetriever(ResponseData data, HttpClient httpClient)
@@ -496,7 +515,7 @@ private List<string> GetArgValues(ArgumentPair pair)
496515
hasCompleter = param.HasCompleter;
497516
}
498517

499-
if (_stop || !hasCompleter || s_azPythonPath is null) { return null; }
518+
if (_stop || !hasCompleter || s_azCompleteCmd is null) { return null; }
500519

501520
// Then, try to get dynamic argument values using AzCLI tab completion.
502521
string commandLine = $"{pair.Command} {pair.Parameter} ";
@@ -510,11 +529,14 @@ private List<string> GetArgValues(ArgumentPair pair)
510529
{
511530
StartInfo = new ProcessStartInfo()
512531
{
513-
FileName = s_azPythonPath,
514-
Arguments = "-Im azure.cli",
532+
FileName = s_azCompleteCmd,
533+
Arguments = s_azCompleteArg,
515534
UseShellExecute = false,
516535
RedirectStandardOutput = true,
517536
RedirectStandardError = true,
537+
// Redirect stdin to force installing a missing extension, otherwise 'az'
538+
// may prompt interactively for user's approval to install.
539+
RedirectStandardInput = true,
518540
}
519541
};
520542

0 commit comments

Comments
 (0)