Repository: microsoft/semantic-kernel
File: dotnet/src/IntegrationTests/Plugins/ContextualFunctionProviderTests.cs (C#)

Code before:
    [Fact]
    private async Task ItShouldSelectFunctionsBasedOnPreviousAndCurrentInvocationContextAsync()
    {
        // Arrange
        IList<AIFunction>? relevantFunctions = null;

        void OnModelInvokingAsync(ICollection<ChatMessage> newMessages, AIContext context)
        {
            relevantFunctions = context.AIFunctions;
        }

        ChatCompletionAgent agent =
            new()
            {
                Name = "AzureAssistant",
                Instructions = "You are a helpful assistant that helps with Azure resource management. " +
                               "Avoid including the phrase like 'If you need further assistance or have any additional tasks, feel free to let me know!' in any responses.",
                Kernel = this._kernel,
                Arguments = new(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: new FunctionChoiceBehaviorOptions { RetainArgumentTypes = true }) })
            };

        ContextualFunctionProvider provider = new(
            vectorStore: this._vectorStore,
            vectorDimensions: this._modelDimensions,
            functions: GetAvailableFunctions(),
            maxNumberOfFunctions: 2, // Instruct the provider to return only one relevant function
            options: new ContextualFunctionProviderOptions
            {
                NumberOfRecentMessagesInContext = 1 // Use only the last message from the previous agent invocation  
            }
        );

        ChatHistoryAgentThread agentThread = new();
        agentThread.AIContextProviders.Add(new AIContextProviderDecorator(provider, OnModelInvokingAsync));

        // Act
        await agent.InvokeAsync("Please provision a VM on Azure", agentThread).FirstAsync();

        // Assert
        Assert.NotNull(relevantFunctions);
        Assert.Contains(relevantFunctions, f => f.Name == "ProvisionVM");

        // Act: Ask agent to deploy the VM provisioned in the previous invocation
        await agent.InvokeAsync("Deploy it", agentThread).FirstAsync();

        // Assert
        Assert.NotNull(relevantFunctions);
        Assert.Contains(relevantFunctions, f => f.Name == "DeployVM");
    }

    /// <summary>

Review comment (suggestion):
```suggestion
            maxNumberOfFunctions: 2, // Instruct the provider to return two relevant functions
```

Code after:
    [Fact]
    private async Task ItShouldSelectFunctionsBasedOnPreviousAndCurrentInvocationContextAsync()
    {
        // Arrange
        IList<AIFunction>? relevantFunctions = null;

        void OnModelInvokingAsync(ICollection<ChatMessage> newMessages, AIContext context)
        {
            relevantFunctions = context.AIFunctions;
        }

        ChatCompletionAgent agent =
            new()
            {
                Name = "AzureAssistant",
                Instructions = "You are a helpful assistant that helps with Azure resource management. " +
                               "Avoid including the phrase like 'If you need further assistance or have any additional tasks, feel free to let me know!' in any responses.",
                Kernel = this._kernel,
                Arguments = new(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: new FunctionChoiceBehaviorOptions { RetainArgumentTypes = true }) })
            };

        ContextualFunctionProvider provider = new(
            vectorStore: this._vectorStore,
            vectorDimensions: this._modelDimensions,
            functions: GetAvailableFunctions(),
            maxNumberOfFunctions: 1, // Instruct the provider to return only one relevant function
            options: new ContextualFunctionProviderOptions
            {
                NumberOfRecentMessagesInContext = 1, // Use only the last message from the previous agent invocation
                ContextEmbeddingValueProvider = (recentMessages, newMessages, _) =>
                {
                    string context;

                    // Provide a deterministic context for the VM deployment request instead of using the one assembled by the provider based on
                    // the LLM's non-deterministic response for the VM provisioning request. This is done to ensure that the context is always
                    // the same for the VM deployment request; otherwise, the non-deterministic context could lead to different function selection
                    // results for the same VM deployment request, resulting in test flakiness.  
                    if (newMessages.Any(m => m.Text.Contains("Deploy it")))
                    {
                        context = "A VM has been successfully provisioned with the ID: 40a2d11e-233b-409e-8638-9d4508623b93.\r\nDeploy it";
                    }
                    else
                    {
                        context = string.Join(
                            Environment.NewLine,
                            recentMessages
                            .TakeLast(1)
                            .Where(m => !string.IsNullOrWhiteSpace(m?.Text))
                            .Select(m => m.Text));
                    }