Skip to content

Commit 221108d

Browse files
yemohylemsJinLeiVeryEarlydingmeng-xuemsJinLei
authored
Add Variety to Az.Predictor (#13480)
* psd1 & psm1 of Az.Installer with a demo cmdlet (#12698) * Internal/az.installer (#12817) * add util functions * add install-azmodule * add log to cmdlets * move verbose messages to debug * move under tools\ * polish warning message * move install-azmodule to exports * export install-azmodule * rename to az.tools.installer * Internal/az.installer (#12860) * add util functions * add install-azmodule * add log to cmdlets * move verbose messages to debug * move under tools\ * polish warning message * move install-azmodule to exports * export install-azmodule * rename to az.tools.installer * add uninstall-AzModule * Cmdlet Update-AzModule (#12832) * Update-AzModule * Address to PM requirements 1. Remove prefix Az. when input module name 2. update calculate from most recently installed respositories of different modules 3. reorder the sequence of module udpate and uninstall 4. other bug fix * Add telemetry * Support telemetry * Move Get-AzModuleUpdateList to internal (#12865) * add telemetry to Uninstall-AzModule cmdlet * bugfix: module name was not handled properly * Add environment variable to disable telemetry * parallel executing Install/Uninstall module * update code after review * improve performance * Fix Update-AzModule issues * bug fix * remove unused util * remove az.accounts when allow preview * Fix issue when no module to udpate * Add sign pipeline * skip confirmation when remove-job * remove debug info * fix parameter reference * Initial checking in AzPredictor (#12847) - It contains an implementation of ICommandPredictor that provides predictions to PSReadLine. - It also talks to the service endpoints to get the predictions. - It reads from the profile settings about the service endpoint. - There are some tests cases. * filter installedmodules before uninstall * bugfix for uninstall * Add synopsis and example to exported cmdlets * add default parameter set for uninstall-azmodule * add input validatin * remove unnecessary warning message * Build and package module under artifacts folder * Improve Az.Tool.Predictor (#12922) * Set up the dependencies on the PSReadline 2.1.0 * Initialize the env when the module is imported. - Add a script AzPredictor.ps1 to set the psreadline prediction view and source. - The script is run when the module is imported. * Fix a bug when loading settings from user profile. - The settings from user profile may not exist. In this case we should just ignore it and use the default one. * Fix issues in getting settings and send requests. - Fix the way to get the Azure PowerShell settings regarding collecting telemetry. - Avoid sending multiple requests while there is one running. * Use the NuGet pacakges from nuget.org. - Remove the local feed for those NuGet packages. * Rename namespace/assemblies/module name * Collect telemetry where we get the prediction. * Make some classes internal. * Add dependencies on Az module - This avoid the issue that our module loads Microsoft.Azure.PowerShell.Common dlls and Az tries to load it too. * Remove ps1 file that sets psreadline options. - We should instruct the users to set the options by themselves. * Remove psreadline module since it's not released. * Fix the merge issue * Add Az as external dependency * Add pipeline 'sign-tool-predictor' * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * net.webclient.downloadfile * refine command * clean build * Update sign-tool-predictor.yml for Azure Pipelines * Improve the build of Az.Tools.Predictor (#12974) * Change the build for Az.Tools.Predictor - Do a 'dotnet publish' instead of 'dotnet build' when the configuration is release. - When the configuration is release, replace the output folder with the ones from publish folder. The output folder is where the package retrieve the contents from. This will have the module and all the dependencies in the package. - The package target only runs when the configuration is release. - Add a target Test to run the unit tests. - Update the build command in azure pipeline to build with configuration release. * Specify the sub-folder artifact for each tool. - The build process involves deleting the artifact folders. And each tool shares the same artifact folder. This may be an issue if we build them in parralel because the build process of a tool will delete the folder while another tool is being built. - We'll use sub-folder for each tool in the artifact folder. Co-authored-by: Beisi Zhou <[email protected]> * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Override powershellcorecommandPrefix * join_path * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Install Az * Update sign-tool-predictor.yml for Azure Pipelines * Update sign-tool-predictor.yml for Azure Pipelines * Sign dll * Remove dll sign * Predict parameter values in the suggestion (#12984) * Get the parameter value from the history. * Add a mock ps console for testing purpose. - The mock ps console will echo back most of the commands. So that we don't need to really execute the Az command on Azure to test the prediction. * improve telemetry (#13025) * Correlate the telemetry event we send. - We have these telemetry entry points when we provide suggestion, when a suggestion is accepted, and when the user executes some command. We add a SuggestionId to the telemetry events so that we can correlate those three events. Doing that we know what suggestions are provided, accepted, and executed. * Collect and correlate our telemetry event. - With this change, we have these telemetry events; * RequestPrediction * GetSuggestion * AcceptSuggestion * CommandHistory - The events can be correlated by the session id and correlate id that are associate with the events. * Fix the request body. * Rename the prediction source. * Collect telemetry when an error occurs. * Remove some PII field * Collect user input in GetSuggestion event. * Use a common telemetry event prefix. * Remove the .gitignore that shouldn't be added. * Clean up the code. * return multiple suggestion (#13098) * Return multiple suggestions. - Add a setting to configure at most how many suggestions to return. - We'll go through the command/parameters one by one and to construct the suggestion. We may return multiple suggestions for the same command but with different parameter sets; * Use camel casing in the setting fields. - Looks like other json file in $HOME/.azure use camel case or PascalCase. None use snake case. * Fix a logic error. - We'll use the command list for suggestion while the prediction list isn't available. * Stop finding suggestion when the count is met. * Improve the MockPSConsole. * Cache the last two commands from the history. * Reduce the dependencies on Azure powershell common. (#13113) - That assembly and its dependencies causes a conflict if we load this module and Az.Accounts module. Though we can work around by sepcifying Az as a dependencies on this module, that'll cause long loading time. - The reason of loading that assembly is to get the setting about Azure PowerShell data collection. We can copy part of the code to load that file, so that we don't need that assembly as the dependency. * Add a missing file. (#13234) * Fix duplicate text (#13326) * Improve the debugging experience. - GetSuggestion gets cancelled during debugging because it times out. So we use an environment variable to control whether to allow cancellation from psreadline. - Use another macro to control if print message for telemetry. * Fix a bug that the command line is repeated in the suggestion. - When we parse the command line and there is an incomplete parameter list, we repeat the command line in the suggestion. - The cause is that we parse the command line and get the wrong parameter set from the user input * Update how we send request and collect telemetry (#13327) * Fix the query * Reduce the number of requests to the service. - We request the prediction for the command history. When the command history isn't changed, we don't need to request the prediction again. * Not to collect the parameter value in the telemetry. * add variety to predictions list * add variety to predictions list * Bug fixes and performance improvement (#13410) * Reduce extra cost to the perf issue. * Remove the aggregation on the parameter set. * Fix an issue * Fix some comments. * Improve the telemetry and http request (#13354) * Collect user id and mac address. - We hash the user account id and the mac address, and collect those in the telemetry. These are used to find how many users are using this mdoule. - We also send the hashed user account id in the http request header. This is used to enable throttling by user account. * Rename * Collect more data for diagnostic purpose. * Fix typo * Remove getting Az modules versions. * Fixed issue of duplicate threshold consistency caused by two Query function calls as well as duplicate tolerance when list of novel commands is insufficiently small * Fixed issue of duplicate threshold consistency caused by two Query function calls as well as duplicate tolerance when list of novel commands is insufficiently small * remove commented lines, change Dictionary to IDictionary Co-authored-by: Jin Lei <[email protected]> Co-authored-by: Yabo Hu <[email protected]> Co-authored-by: dingmeng-xue <[email protected]> Co-authored-by: msJinLei <[email protected]> Co-authored-by: msJinLei <[email protected]> Co-authored-by: kceiw <[email protected]> Co-authored-by: Beisi Zhou <[email protected]> Co-authored-by: Beisi Zhou <[email protected]>
1 parent a96ccb7 commit 221108d

File tree

9 files changed

+62
-33
lines changed

9 files changed

+62
-33
lines changed

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/AzPredictorServiceTests.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ public AzPredictorServiceTests(ModelFixture fixture)
6262
public void VerifyUsingSuggestion(string userInput)
6363
{
6464
var predictionContext = PredictionContext.Create(userInput);
65-
var expected = this._suggestionsPredictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
66-
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
65+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
66+
var expected = this._suggestionsPredictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
67+
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, 1, CancellationToken.None);
6768
Assert.NotEmpty(actual);
6869
Assert.NotNull(actual.First().Item1);
69-
Assert.Equal(expected.First().Key, actual.First().Item1);
70+
Assert.Equal(expected.Item1.First().Key, actual.First().Item1);
7071
Assert.Equal(PredictionSource.CurrentCommand, actual.First().Item3);
7172
}
7273

@@ -79,11 +80,12 @@ public void VerifyUsingSuggestion(string userInput)
7980
public void VerifyUsingCommand(string userInput)
8081
{
8182
var predictionContext = PredictionContext.Create(userInput);
82-
var expected = this._commandsPredictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
83-
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
83+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
84+
var expected = this._commandsPredictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
85+
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, 1, CancellationToken.None);
8486
Assert.NotEmpty(actual);
8587
Assert.NotNull(actual.First().Item1);
86-
Assert.Equal(expected.First().Key, actual.First().Item1);
88+
Assert.Equal(expected.Item1.First().Key, actual.First().Item1);
8789
Assert.Equal(PredictionSource.StaticCommands, actual.First().Item3);
8890
}
8991

@@ -101,7 +103,7 @@ public void VerifyUsingCommand(string userInput)
101103
public void VerifyNoPrediction(string userInput)
102104
{
103105
var predictionContext = PredictionContext.Create(userInput);
104-
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
106+
var actual = this._service.GetSuggestion(predictionContext.InputAst, 1, 1, CancellationToken.None);
105107
Assert.Empty(actual);
106108
}
107109
}

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/AzPredictorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public void VerifySupportedCommandMasked()
142142
public void VerifySuggestion(string userInput)
143143
{
144144
var predictionContext = PredictionContext.Create(userInput);
145-
var expected = this._service.GetSuggestion(predictionContext.InputAst, 1, CancellationToken.None);
145+
var expected = this._service.GetSuggestion(predictionContext.InputAst, 1, 1, CancellationToken.None);
146146
var actual = this._azPredictor.GetSuggestion(predictionContext, CancellationToken.None);
147147

148148
Assert.Equal(expected.Select(e => e.Item1), actual.Select(a => a.SuggestionText));

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/PredictorTests.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ public PredictorTests(ModelFixture fixture)
5050
public void GetNullPredictionWithCommandName(string userInput)
5151
{
5252
var predictionContext = PredictionContext.Create(userInput);
53-
var result = this._predictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
54-
Assert.Empty(result);
53+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
54+
var result = this._predictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
55+
Assert.Empty(result.Item1);
5556
}
5657

5758
/// <summary>
@@ -66,8 +67,9 @@ public void GetNullPredictionWithCommandName(string userInput)
6667
public void GetPredictionWithCommandName(string userInput)
6768
{
6869
var predictionContext = PredictionContext.Create(userInput);
69-
var result = this._predictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
70-
Assert.NotEmpty(result);
70+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
71+
var result = this._predictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
72+
Assert.NotEmpty(result.Item1);
7173
}
7274

7375
/// <summary>
@@ -81,8 +83,9 @@ public void GetPredictionWithCommandName(string userInput)
8183
public void GetPredictionWithCommandNameParameters(string userInput)
8284
{
8385
var predictionContext = PredictionContext.Create(userInput);
84-
var result = this._predictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
85-
Assert.NotEmpty(result);
86+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
87+
var result = this._predictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
88+
Assert.NotEmpty(result.Item1);
8689
}
8790

8891
/// <summary>
@@ -97,8 +100,9 @@ public void GetPredictionWithCommandNameParameters(string userInput)
97100
public void GetNullPredictionWithCommandNameParameters(string userInput)
98101
{
99102
var predictionContext = PredictionContext.Create(userInput);
100-
var result = this._predictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
101-
Assert.Empty(result);
103+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
104+
var result = this._predictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
105+
Assert.Empty(result.Item1);
102106
}
103107

104108
/// <summary>
@@ -108,9 +112,10 @@ public void GetNullPredictionWithCommandNameParameters(string userInput)
108112
public void VerifyPredictionForCommand()
109113
{
110114
var predictionContext = PredictionContext.Create("Connect-AzAccount");
111-
var result = this._predictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
115+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
116+
var result = this._predictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
112117

113-
Assert.Equal("Connect-AzAccount -Credential <PSCredential> -ServicePrincipal -Tenant <>", result.First().Key);
118+
Assert.Equal("Connect-AzAccount -Credential <PSCredential> -ServicePrincipal -Tenant <>", result.Item1.First().Key);
114119
}
115120

116121
/// <summary>
@@ -120,9 +125,10 @@ public void VerifyPredictionForCommand()
120125
public void VerifyPredictionForCommandAndParameters()
121126
{
122127
var predictionContext = PredictionContext.Create("GET-AZSTORAGEACCOUNTKEY -NAME");
123-
var result = this._predictor.Query(predictionContext.InputAst, 1, CancellationToken.None);
128+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
129+
var result = this._predictor.Query(predictionContext.InputAst, presentCommands, 1, 1, CancellationToken.None);
124130

125-
Assert.Equal("Get-AzStorageAccountKey -Name 'ContosoStorage' -ResourceGroupName 'ContosoGroup02'", result.First().Key);
131+
Assert.Equal("Get-AzStorageAccountKey -Name 'ContosoStorage' -ResourceGroupName 'ContosoGroup02'", result.Item1.First().Key);
126132
}
127133
}
128134
}

tools/Az.Tools.Predictor/Az.Tools.Predictor/AzPredictor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public List<PredictiveSuggestion> GetSuggestion(PredictionContext context, Cance
184184
{
185185
maskedUserInput = AzPredictor.MaskCommandLine(context.InputAst.FindAll((ast) => ast is CommandAst, true).LastOrDefault() as CommandAst);
186186

187-
suggestions = _service.GetSuggestion(context.InputAst, _settings.SuggestionCount.Value, localCancellationToken);
187+
suggestions = _service.GetSuggestion(context.InputAst, _settings.SuggestionCount.Value, _settings.MaxAllowedCommandDuplicate.Value, localCancellationToken);
188188

189189
localCancellationToken.ThrowIfCancellationRequested();
190190

tools/Az.Tools.Predictor/Az.Tools.Predictor/AzPredictorService.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,17 @@ protected virtual void Dispose(bool disposing)
125125
/// <remarks>
126126
/// Queries the Predictor with the user input if predictions are available, otherwise uses commands
127127
/// </remarks>
128-
public IEnumerable<ValueTuple<string, string, PredictionSource>> GetSuggestion(Ast input, int suggestionCount, CancellationToken cancellationToken)
128+
public IEnumerable<ValueTuple<string, string, PredictionSource>> GetSuggestion(Ast input, int suggestionCount, int maxAllowedCommandDuplicate, CancellationToken cancellationToken)
129129
{
130130
var commandSuggestions = this._commandSuggestions;
131131
var command = this._commandForPrediction;
132132

133133
IList<ValueTuple<string, string, PredictionSource>> results = new List<ValueTuple<string, string, PredictionSource>>();
134+
var presentCommands = new System.Collections.Generic.Dictionary<string, int>();
135+
var resultsFromSuggestionTuple = commandSuggestions?.Item2?.Query(input, presentCommands, suggestionCount, maxAllowedCommandDuplicate, cancellationToken);
136+
var resultsFromSuggestion = resultsFromSuggestionTuple.Item1;
137+
presentCommands = resultsFromSuggestionTuple.Item2.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
134138

135-
var resultsFromSuggestion = commandSuggestions?.Item2?.Query(input, suggestionCount, cancellationToken);
136139

137140
if (resultsFromSuggestion != null)
138141
{
@@ -159,7 +162,9 @@ public IEnumerable<ValueTuple<string, string, PredictionSource>> GetSuggestion(A
159162
if ((resultsFromSuggestion == null) || (resultsFromSuggestion.Count() < suggestionCount))
160163
{
161164
var commands = this._commands;
162-
var resultsFromCommands = commands?.Query(input, suggestionCount - resultsFromSuggestion.Count(), cancellationToken);
165+
var resultsFromCommandsTuple = commands?.Query(input, presentCommands,suggestionCount - resultsFromSuggestion.Count(), maxAllowedCommandDuplicate, cancellationToken);
166+
var resultsFromCommands = resultsFromCommandsTuple.Item1;
167+
presentCommands = resultsFromCommandsTuple.Item2.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
163168

164169
if (resultsFromCommands != null)
165170
{
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2-
"serviceUri": "https://app.aladdin.microsoft.com/api/v1",
2+
"maxAllowedCommandDuplicate": 1,
3+
"serviceUri": "https://app.aladdin.microsoft.com/api/v1",
34
"suggestionCount": 7
45
}

tools/Az.Tools.Predictor/Az.Tools.Predictor/IAzPredictorService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ public interface IAzPredictorService
2929
/// </summary>
3030
/// <param name="input">User input from PSReadLine</param>
3131
/// <param name="suggestionCount">The number of suggestion to return.</param>
32+
/// <param name="maxAllowedCommandDuplicate">The maximum amount of the same commnds in the list of predictions.</param>
3233
/// <param name="cancellationToken">The cancellation token</param>
3334
/// <returns>The list of suggestions for <paramref name="input"/> and the source that create the suggestion. The maximum number of suggestion is <paramref name="suggestionCount"/></returns>
34-
public IEnumerable<ValueTuple<string, string, PredictionSource>> GetSuggestion(Ast input, int suggestionCount, CancellationToken cancellationToken);
35+
public IEnumerable<ValueTuple<string, string, PredictionSource>> GetSuggestion(Ast input, int suggestionCount, int maxAllowedCommandDuplicate, CancellationToken cancellationToken);
3536

3637
/// <summary>
3738
/// Requests predictions, given a command string.

tools/Az.Tools.Predictor/Az.Tools.Predictor/Predictor.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@ public Predictor(IList<string> modelPredictions, ParameterValuePredictor paramet
5757
/// Given a user input PowerShell AST, returns prediction text.
5858
/// </summary>
5959
/// <param name="input">PowerShell AST input of the user, generated by PSReadLine</param>
60+
/// <param name="presentCommands">Commands already present.</param>
6061
/// <param name="suggestionCount">The number of suggestion to return.</param>
62+
/// <param name="maxAllowedCommandDuplicate">The maximum amount of the same commnds in the list of predictions.</param>
6163
/// <param name="cancellationToken">The cancellation token</param>
6264
/// <returns>The collection of suggestions. The key is the predicted text adjusted based on <paramref name="input"/>. The
6365
/// value is the original text to create the adjusted text. </returns>
64-
public IDictionary<string, string> Query(Ast input, int suggestionCount, CancellationToken cancellationToken)
66+
public Tuple<IDictionary<string, string>, IDictionary<string, int>> Query(Ast input, IDictionary<string, int> presentCommands, int suggestionCount, int maxAllowedCommandDuplicate, CancellationToken cancellationToken)
6567
{
6668
if (suggestionCount <= 0)
6769
{
@@ -77,6 +79,7 @@ public IDictionary<string, string> Query(Ast input, int suggestionCount, Cancell
7779
}
7880

7981
var results = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
82+
var resultsTemp = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
8083

8184
try
8285
{
@@ -102,9 +105,7 @@ public IDictionary<string, string> Query(Ast input, int suggestionCount, Cancell
102105
var resultBuilder = new StringBuilder();
103106
var usedParams = new HashSet<int>();
104107
var sourceBuilder = new StringBuilder();
105-
var presentCommands = new System.Collections.Generic.Dictionary<string, int>(); // Added
106-
int maxAllowedCommandDupl = 1;
107-
108+
108109
for (var i = 0; i < _predictions.Count && results.Count < suggestionCount; ++i)
109110
{
110111
if (commandNameQuery(_predictions[i].Command))
@@ -148,11 +149,15 @@ public IDictionary<string, string> Query(Ast input, int suggestionCount, Cancell
148149
results.Add(prediction.ToString(), sourceBuilder.ToString());
149150
presentCommands.Add(_predictions[i].Command, 1);
150151
}
151-
else if (presentCommands[_predictions[i].Command] < maxAllowedCommandDupl)
152+
else if (presentCommands[_predictions[i].Command] < maxAllowedCommandDuplicate)
152153
{
153154
results.Add(prediction.ToString(), sourceBuilder.ToString());
154155
presentCommands[_predictions[i].Command] += 1;
155156
}
157+
else
158+
{
159+
resultsTemp.Add(prediction.ToString(), sourceBuilder.ToString());
160+
}
156161

157162
if (results.Count == suggestionCount)
158163
{
@@ -166,8 +171,11 @@ public IDictionary<string, string> Query(Ast input, int suggestionCount, Cancell
166171
catch
167172
{
168173
}
169-
170-
return results;
174+
if ((results.Count < suggestionCount) && (resultsTemp.Count >0))
175+
{
176+
resultsTemp.ToList().GetRange(0, suggestionCount - results.Count).ForEach(x => results.Add(x.Key,x.Value));
177+
}
178+
return new Tuple<IDictionary<string, string>, IDictionary<string, int>>(results, presentCommands);
171179
}
172180

173181
/// <summary>

tools/Az.Tools.Predictor/Az.Tools.Predictor/Settings.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ sealed class Settings
4040
/// The number of suggestions to return to PSReadLine
4141
/// </summary>
4242
public int? SuggestionCount { get; set; }
43+
public int? MaxAllowedCommandDuplicate { get; set; }
4344

4445
private static bool? _isContinueOnTimeout;
4546
/// <summary>
@@ -121,6 +122,11 @@ private void OverrideSettingsFromProfile()
121122
{
122123
this.SuggestionCount = profileSettings.SuggestionCount;
123124
}
125+
126+
if (profileSettings.MaxAllowedCommandDuplicate.HasValue && (profileSettings.MaxAllowedCommandDuplicate.Value > 0))
127+
{
128+
this.MaxAllowedCommandDuplicate = profileSettings.MaxAllowedCommandDuplicate;
129+
}
124130
}
125131
catch
126132
{

0 commit comments

Comments
 (0)