Skip to content

Include a sample with RunStreamingAsync for function-tools-approvals.md #310

@jozkee

Description

@jozkee

For https://github.com/MicrosoftDocs/semantic-kernel-docs/blob/cf43318c5d7616f2dd8a731b3355646d3968218a/agent-framework/tutorials/agents/function-tools-approvals.md

Since streaming APIs add a grade of complexity, It would be nice to include a sample in how users can handle approvals with IAsyncEnumerable-based APIs.

using System;
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
#pragma warning disable MEAI001

AIFunction weatherFunction = AIFunctionFactory.Create(GetWeather);
AIFunction approvalRequiredWeatherFunction = new ApprovalRequiredAIFunction(weatherFunction);

AIAgent agent = new AzureOpenAIClient(
    new Uri("https://<myresource>.openai.azure.com"),
    new AzureCliCredential())
        .GetChatClient("gpt-4o-mini")
        .CreateAIAgent(instructions: "You are a helpful assistant", tools: [approvalRequiredWeatherFunction]);

AgentThread thread = agent.GetNewThread();
var response = agent.RunStreamingAsync("What is the weather like in Amsterdam?", thread);

while (true)
{
    List<FunctionApprovalRequestContent> functionApprovalRequests = [];
    await foreach (AgentRunResponseUpdate update in response)
    {
        if (update.Contents.OfType<FunctionApprovalRequestContent>().ToList() is { Count: > 0 } approvals)
        {
            functionApprovalRequests.AddRange(approvals);
        }
        else if (update.Text is { Length: > 0 } text)
        {
            Console.WriteLine(text);
        }
    }

    if (functionApprovalRequests.FirstOrDefault() is { } requestContent)
    {
        Console.WriteLine($"We require approval to execute '{requestContent.FunctionCall.Name}'");
        var approvalMessage = new ChatMessage(ChatRole.User, [requestContent.CreateResponse(true)]);
        response = agent.RunStreamingAsync(approvalMessage, thread);
    }
    else
    {
        break;
    }
}

[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
    => $"The weather in {location} is cloudy with a high of 15°C.";

cc @westey-m @stephentoub

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions