/// <inhericdoc /> public List <PredictiveSuggestion> GetSuggestion(PredictionContext context, CancellationToken cancellationToken) { if (_settings.SuggestionCount.Value <= 0) { return(new List <PredictiveSuggestion>()); } Exception exception = null; CommandLineSuggestion suggestions = null; try { var localCancellationToken = Settings.ContinueOnTimeout ? CancellationToken.None : cancellationToken; suggestions = _service.GetSuggestion(context, _settings.SuggestionCount.Value, _settings.MaxAllowedCommandDuplicate.Value, localCancellationToken); var returnedValue = suggestions?.PredictiveSuggestions?.ToList(); return(returnedValue ?? new List <PredictiveSuggestion>()); } catch (Exception e) when(!(e is OperationCanceledException)) { exception = e; return(new List <PredictiveSuggestion>()); } finally { _telemetryClient.OnGetSuggestion(new GetSuggestionTelemetryData(context.InputAst, suggestions, cancellationToken.IsCancellationRequested, exception)); } }
/// <inhericdoc /> public SuggestionPackage GetSuggestion(PredictionClient client, PredictionContext context, CancellationToken cancellationToken) { var localSuggestionSessionId = _suggestionSessionId++; if (!_isInitialized || _settings.SuggestionCount.Value <= 0) { return(CreateResult(null)); } Exception exception = null; CommandLineSuggestion suggestions = null; try { var localCancellationToken = Settings.ContinueOnTimeout ? CancellationToken.None : cancellationToken; suggestions = _service.GetSuggestion(context, _settings.SuggestionCount.Value, _settings.MaxAllowedCommandDuplicate.Value, localCancellationToken); var returnedValue = suggestions?.PredictiveSuggestions?.ToList(); return(CreateResult(returnedValue)); } catch (Exception e) when(!(e is OperationCanceledException)) { exception = e; return(CreateResult(null)); } finally { _telemetryClient.OnGetSuggestion(new GetSuggestionTelemetryData(client, localSuggestionSessionId, context.InputAst, suggestions, cancellationToken.IsCancellationRequested, exception)); } SuggestionPackage CreateResult(List <PredictiveSuggestion> suggestions) { if ((suggestions == null) || (suggestions.Count == 0)) { return(default(SuggestionPackage)); } // Replace the last suggestion with "Open-AzPredictorSurvey". if (suggestions.Count == _settings.SuggestionCount.Value) { suggestions[suggestions.Count - 1] = _surveySuggestions[_azContext?.Cohort ?? 0]; } else { suggestions.Add(_surveySuggestions[_azContext?.Cohort ?? 0]); } return(new SuggestionPackage(localSuggestionSessionId, suggestions)); } }
/// <inhericdoc /> public SuggestionPackage GetSuggestion(string clientId, PredictionContext context, CancellationToken cancellationToken) { var localSuggestionSessionId = _suggestionSessionId++; if (_settings.SuggestionCount.Value <= 0) { return(CreateResult(null)); } Exception exception = null; CommandLineSuggestion suggestions = null; try { var localCancellationToken = Settings.ContinueOnTimeout ? CancellationToken.None : cancellationToken; suggestions = _service.GetSuggestion(context, _settings.SuggestionCount.Value, _settings.MaxAllowedCommandDuplicate.Value, localCancellationToken); var returnedValue = suggestions?.PredictiveSuggestions?.ToList(); return(CreateResult(returnedValue)); } catch (Exception e) when(!(e is OperationCanceledException)) { exception = e; return(CreateResult(null)); } finally { _telemetryClient.OnGetSuggestion(new GetSuggestionTelemetryData(clientId, localSuggestionSessionId, context.InputAst, suggestions, cancellationToken.IsCancellationRequested, exception)); } SuggestionPackage CreateResult(List <PredictiveSuggestion> suggestions) { if ((suggestions == null) || (suggestions.Count == 0)) { return(default(SuggestionPackage)); } return(new SuggestionPackage(localSuggestionSessionId, suggestions)); } }
/// <inheritdoc/> /// <remarks> /// Tries to get the suggestions for the user input from the command history. If that doesn't find /// <paramref name="suggestionCount"/> suggestions, it'll fallback to find the suggestion regardless of command history. /// </remarks> public virtual CommandLineSuggestion GetSuggestion(PredictionContext context, int suggestionCount, int maxAllowedCommandDuplicate, CancellationToken cancellationToken) { Validation.CheckArgument(context, $"{nameof(context)} cannot be null"); Validation.CheckArgument <ArgumentOutOfRangeException>(suggestionCount > 0, $"{nameof(suggestionCount)} must be larger than 0."); Validation.CheckArgument <ArgumentOutOfRangeException>(maxAllowedCommandDuplicate > 0, $"{nameof(maxAllowedCommandDuplicate)} must be larger than 0."); var relatedAsts = context.RelatedAsts; CommandAst commandAst = null; for (var i = relatedAsts.Count - 1; i >= 0; --i) { if (relatedAsts[i] is CommandAst c) { commandAst = c; break; } } if (commandAst == null) { return(null); } var commandName = commandAst.GetCommandName(); if (string.IsNullOrWhiteSpace(commandName)) { return(null); } ParameterSet inputParameterSet = null; try { inputParameterSet = new ParameterSet(commandAst, _azContext); } catch when(!IsRecognizedCommand(commandName)) { // We only ignore the exception when the command name is not supported. // We want to collect the telemetry about the exception how common it is for the format we don't support. return(null); } cancellationToken.ThrowIfCancellationRequested(); // We want to show a survey/feedback cmdlet at the end of the suggestion list. We try to find one less // suggestions to make room for that cmdlet and avoid too much computation. // But if only one suggestion is requested, we don't replace it with the survey cmdlets. var suggestionFromPredictorCount = (suggestionCount == 1) ? 1 : (suggestionCount - 1); var rawUserInput = context.InputAst.ToString(); var presentCommands = new Dictionary <string, int>(); var commandBasedPredictor = _commandBasedPredictor; var commandToRequestPrediction = _commandToRequestPrediction; var result = commandBasedPredictor?.Item2?.GetSuggestion(commandName, inputParameterSet, rawUserInput, presentCommands, suggestionFromPredictorCount, maxAllowedCommandDuplicate, cancellationToken); if ((result != null) && (result.Count > 0)) { var suggestionSource = SuggestionSource.PreviousCommand; if (string.Equals(commandToRequestPrediction, commandBasedPredictor?.Item1, StringComparison.Ordinal)) { suggestionSource = SuggestionSource.CurrentCommand; } for (var i = 0; i < result.Count; ++i) { result.UpdateSuggestionSource(i, suggestionSource); } } if ((result == null) || (result.Count < suggestionFromPredictorCount)) { var fallbackPredictor = _fallbackPredictor; var suggestionCountToRequest = (result == null) ? suggestionFromPredictorCount : suggestionFromPredictorCount - result.Count; var resultsFromFallback = fallbackPredictor?.GetSuggestion(commandName, inputParameterSet, rawUserInput, presentCommands, suggestionCountToRequest, maxAllowedCommandDuplicate, cancellationToken); if ((result == null) && (resultsFromFallback != null)) { result = resultsFromFallback; for (var i = 0; i < result.Count; ++i) { result.UpdateSuggestionSource(i, SuggestionSource.StaticCommands); } } else if ((resultsFromFallback != null) && (resultsFromFallback.Count > 0)) { for (var i = 0; i < resultsFromFallback.Count; ++i) { result.AddSuggestion(resultsFromFallback.PredictiveSuggestions[i], resultsFromFallback.SourceTexts[i], SuggestionSource.StaticCommands); } } } if (suggestionCount > 1) { // Add the survey/feedback cmdlet at the end if the user isn't typing it. bool isSurveyCmdletFound = false; if (result != null) { foreach (var predictiveCommand in result.SourceTexts) { if (string.Equals(predictiveCommand, _surveyCmdlets[_azContext.Cohort].Command, StringComparison.Ordinal)) { isSurveyCmdletFound = true; break; } } } else { result = new CommandLineSuggestion(); } if (!isSurveyCmdletFound) { var toAddCmdlet = _surveyCmdlets[_azContext.Cohort].Command; var toAddDescription = _surveyCmdlets[_azContext.Cohort].Description; result.AddSuggestion(new PredictiveSuggestion($"{toAddCmdlet} # {toAddDescription}", toAddCmdlet), toAddCmdlet, SuggestionSource.StaticCommands); } } return(result); }