Skip to content

Commit 7231ba2

Browse files
authored
Simplify parameter injection UI and fix a few bugs (#246)
1 parent c8c06ee commit 7231ba2

File tree

4 files changed

+61
-48
lines changed

4 files changed

+61
-48
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,10 @@ internal void ReplaceKnownPlaceholders(ResponseData data)
335335
{
336336
string script = command.Script;
337337
command.Script = script.Replace(entry.Key, entry.Value, StringComparison.OrdinalIgnoreCase);
338-
command.Updated = !ReferenceEquals(script, command.Script);
338+
if (!ReferenceEquals(script, command.Script))
339+
{
340+
command.Updated = true;
341+
}
339342
}
340343
}
341344

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ private async Task StartConversationAsync(IHost host, CancellationToken cancella
149149
int chatNumber = conversationState.DailyConversationNumber;
150150
int requestNumber = conversationState.TurnNumber;
151151

152-
host.WriteLine($"\n{activity.Text} This is chat #{chatNumber}, request #{requestNumber}.\n");
152+
host.WriteLine($"\n{activity.Text}\nThis is chat #{chatNumber}, request #{requestNumber}.\n");
153153
return;
154154
}
155155
}

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private void ReplaceAction()
6161
string subText = items.Count > 1
6262
? $"all {items.Count} argument placeholders"
6363
: "the argument placeholder";
64-
host.WriteLine($"\nWe'll provide assistance in replacing {subText} and regenerating the result. You can press 'Enter' to skip to the next parameter or press 'Ctrl+c' to exit the assistance.\n");
64+
host.WriteLine($"\nWe'll provide assistance in replacing {subText} and regenerating the result.\nYou can press 'Enter' to skip to the next parameter or press 'Ctrl+c' to exit the assistance.\n");
6565
host.RenderDivider("Input Values", DividerAlignment.Left);
6666
host.WriteLine();
6767

@@ -72,13 +72,12 @@ private void ReplaceAction()
7272
var item = items[i];
7373
var (command, parameter) = dataRetriever.GetMappedCommand(item.Name);
7474

75-
string desc = item.Desc.TrimEnd('.');
76-
string coloredCmd = parameter is null ? null : SyntaxHighlightAzCommand(command, parameter, item.Name);
77-
string cmdPart = coloredCmd is null ? null : $" [{coloredCmd}]";
78-
79-
host.WriteLine(item.Type is "string"
80-
? $"{i+1}. {desc}{cmdPart}"
81-
: $"{i+1}. {desc}{cmdPart}. Value type: {item.Type}");
75+
string caption = parameter is null ? item.Name : SyntaxHighlightAzCommand(command, parameter, item.Name);
76+
host.WriteLine($"{i+1}. {caption}");
77+
if (item.Name != item.Desc)
78+
{
79+
host.WriteLine(item.Desc);
80+
}
8281

8382
// Get the task for creating the 'ArgumentInfo' object and show a spinner
8483
// if we have to wait for the task to complete.
@@ -109,6 +108,13 @@ private void ReplaceAction()
109108
string value = host.PromptForArgument(argInfo, printCaption: false);
110109
if (!string.IsNullOrEmpty(value))
111110
{
111+
// Add quotes for the value if needed.
112+
value = value.Trim();
113+
if (value.StartsWith('-') || value.Contains(' '))
114+
{
115+
value = $"\"{value}\"";
116+
}
117+
112118
_values.Add(item.Name, value);
113119
_agent.SaveUserValue(item.Name, value);
114120

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

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,15 @@ static DataRetriever()
236236
new("Container Registry",
237237
"cr",
238238
"The name only allows alphanumeric characters. Length: 5 to 50 chars.",
239-
"cr<product>[<environment>][<identifier>]",
239+
"cr<prod>[<env>][<id>]",
240240
["crnavigatorprod001", "crhadoopdev001"],
241241
"az acr create --name",
242242
"New-AzContainerRegistry -Name"),
243243

244244
new("Storage Account",
245245
"st",
246246
"The name can only contain lowercase letters and numbers. Length: 3 to 24 chars.",
247-
"st<product>[<environment>][<identifier>]",
247+
"st<prod>[<env>][<id>]",
248248
["stsalesappdataqa", "sthadoopoutputtest"],
249249
"az storage account create --name",
250250
"New-AzStorageAccount -Name"),
@@ -324,38 +324,50 @@ private void PairPlaceholders(ResponseData data)
324324

325325
foreach (var cmd in data.CommandSet)
326326
{
327-
string script = cmd.Script.Trim();
327+
bool placeholderFound = false;
328+
// Az Copilot may return a code block that contains multiple commands.
329+
string[] scripts = cmd.Script.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
328330

329-
// Handle AzCLI commands.
330-
if (script.StartsWith("az ", StringComparison.OrdinalIgnoreCase))
331+
foreach (string script in scripts)
331332
{
332-
if (!cmds.TryGetValue(script, out command))
333+
// Handle AzCLI commands.
334+
if (script.StartsWith("az ", StringComparison.OrdinalIgnoreCase))
333335
{
334-
int firstParamIndex = script.IndexOf("--");
335-
command = script.AsSpan(0, firstParamIndex).Trim().ToString();
336-
cmds.Add(script, command);
337-
}
336+
if (!cmds.TryGetValue(script, out command))
337+
{
338+
int firstParamIndex = script.IndexOf("--");
339+
command = script.AsSpan(0, firstParamIndex).Trim().ToString();
340+
cmds.Add(script, command);
341+
}
338342

339-
int argIndex = script.IndexOf(item.Name, StringComparison.OrdinalIgnoreCase);
340-
if (argIndex is -1)
341-
{
342-
continue;
343+
int argIndex = script.IndexOf(item.Name, StringComparison.OrdinalIgnoreCase);
344+
if (argIndex is -1)
345+
{
346+
continue;
347+
}
348+
349+
int paramIndex = script.LastIndexOf("--", argIndex);
350+
parameter = script.AsSpan(paramIndex, argIndex - paramIndex).Trim().ToString();
351+
352+
placeholderFound = true;
353+
break;
343354
}
344355

345-
int paramIndex = script.LastIndexOf("--", argIndex);
346-
parameter = script.AsSpan(paramIndex, argIndex - paramIndex).Trim().ToString();
356+
// It's a non-AzCLI command, such as "ssh".
357+
if (script.Contains(item.Name, StringComparison.OrdinalIgnoreCase))
358+
{
359+
// Leave the parameter to be null for non-AzCLI commands, as there is
360+
// no reliable way to parse an arbitrary command
361+
command = script;
362+
parameter = null;
347363

348-
break;
364+
placeholderFound = true;
365+
break;
366+
}
349367
}
350368

351-
// It's a non-AzCLI command, such as "ssh".
352-
if (script.Contains(item.Name, StringComparison.OrdinalIgnoreCase))
369+
if (placeholderFound)
353370
{
354-
// Leave the parameter to be null for non-AzCLI commands, as there is
355-
// no reliable way to parse an arbitrary command
356-
command = script;
357-
parameter = null;
358-
359371
break;
360372
}
361373
}
@@ -421,12 +433,7 @@ private ArgumentInfo CreateArgInfo(ArgumentPair pair)
421433
string cmdAndParam = $"{pair.Command} {pair.Parameter}";
422434
if (s_azNamingRules.TryGetValue(cmdAndParam, out NamingRule rule))
423435
{
424-
string restriction = rule.PatternText is null
425-
? rule.GeneralRule
426-
: $"""
427-
- {rule.GeneralRule}
428-
- Recommended pattern: {rule.PatternText}, e.g. {string.Join(", ", rule.Example)}.
429-
""";
436+
string restriction = rule.PatternText is null ? null : $"Recommended pattern: {rule.PatternText}";
430437
return new ArgumentInfoWithNamingRule(item.Name, item.Desc, restriction, rule);
431438
}
432439

@@ -439,14 +446,11 @@ private ArgumentInfo CreateArgInfo(ArgumentPair pair)
439446

440447
if (_stop) { return null; }
441448

442-
List<string> suggestions = GetArgValues(pair, out Option option);
443-
// If the option's description is less than the placeholder's description in length, then it's
444-
// unlikely to provide more information than the latter. In that case, we don't use it.
445-
string optionDesc = option?.Description?.Length > item.Desc.Length ? option.Description : null;
446-
return new ArgumentInfo(item.Name, item.Desc, optionDesc, dataType, suggestions);
449+
List<string> suggestions = GetArgValues(pair);
450+
return new ArgumentInfo(item.Name, item.Desc, restriction: null, dataType, suggestions);
447451
}
448452

449-
private List<string> GetArgValues(ArgumentPair pair, out Option option)
453+
private List<string> GetArgValues(ArgumentPair pair)
450454
{
451455
// First, try to get static argument values if they exist.
452456
string command = pair.Command;
@@ -466,7 +470,7 @@ private List<string> GetArgValues(ArgumentPair pair, out Option option)
466470
s_azStaticDataCache.TryAdd(command, commandData);
467471
}
468472

469-
option = commandData?.FindOption(pair.Parameter);
473+
Option option = commandData?.FindOption(pair.Parameter);
470474
List<string> staticValues = option?.Arguments;
471475
if (staticValues?.Count > 0)
472476
{
@@ -646,7 +650,7 @@ internal NamingRule(
646650

647651
if (abbreviation is not null)
648652
{
649-
PatternText = $"<product>-{abbreviation}[-<environment>][-<identifier>]";
653+
PatternText = $"<prod>-{abbreviation}[-<env>][-<id>]";
650654
PatternRegex = new Regex($"^(?<prod>[a-zA-Z0-9]+)-{abbreviation}(?:-(?<env>[a-zA-Z0-9]+))?(?:-[a-zA-Z0-9]+)?$", RegexOptions.Compiled);
651655

652656
string product = s_products[Random.Shared.Next(0, s_products.Length)];

0 commit comments

Comments
 (0)