// Copyright (c) Microsoft. All rights reserved. // This sample shows how to use plugins with an AI agent. Plugin classes can // depend on other services that need to be injected. In this sample, the // AgentPlugin class uses the WeatherProvider and CurrentTimeProvider classes // to get weather and current time information. Both services are registered // in the service collection and injected into the plugin. // Plugin classes may have many methods, but only some are intended to be used // as AI functions. The AsAITools method of the plugin class shows how to specify // which methods should be exposed to the AI agent. using Azure.AI.Projects; using Azure.Identity; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; using Microsoft.Extensions.DependencyInjection; using SampleApp; string endpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_AI_PROJECT_ENDPOINT is not set."); string deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-5.4-mini"; const string AssistantInstructions = "You are a helpful assistant that helps people find information."; const string AssistantName = "PluginAssistant"; // Create a service collection to hold the agent plugin and its dependencies. ServiceCollection services = new(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // The plugin depends on WeatherProvider and CurrentTimeProvider registered above. IServiceProvider serviceProvider = services.BuildServiceProvider(); // WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production. // In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid // latency issues, unintended credential probing, and potential security risks from fallback mechanisms. AIProjectClient aiProjectClient = new(new Uri(endpoint), new DefaultAzureCredential()); // Create a ChatClientAgent with the options-based constructor to pass services. AIAgent agent = aiProjectClient.AsAIAgent(new ChatClientAgentOptions { Name = AssistantName, ChatOptions = new() { ModelId = deploymentName, Instructions = AssistantInstructions, Tools = serviceProvider.GetRequiredService().AsAITools().ToList() } }, services: serviceProvider); // Invoke the agent and output the text result. AgentSession session = await agent.CreateSessionAsync(); Console.WriteLine(await agent.RunAsync("Tell me current time and weather in Seattle.", session)); namespace SampleApp { /// /// The agent plugin that provides weather and current time information. /// internal sealed class AgentPlugin { private readonly WeatherProvider _weatherProvider; /// /// Initializes a new instance of the class. /// /// The weather provider to get weather information. public AgentPlugin(WeatherProvider weatherProvider) { this._weatherProvider = weatherProvider; } /// /// Gets the weather information for the specified location. /// /// /// This method demonstrates how to use the dependency that was injected into the plugin class. /// /// The location to get the weather for. /// The weather information for the specified location. public string GetWeather(string location) { return this._weatherProvider.GetWeather(location); } /// /// Gets the current date and time for the specified location. /// /// /// This method demonstrates how to resolve a dependency using the service provider passed to the method. /// /// The service provider to resolve the . /// The location to get the current time for. /// The current date and time as a . public DateTimeOffset GetCurrentTime(IServiceProvider sp, string location) { CurrentTimeProvider currentTimeProvider = sp.GetRequiredService(); return currentTimeProvider.GetCurrentTime(location); } /// /// Returns the functions provided by this plugin. /// /// /// In real world scenarios, a class may have many methods and only a subset of them may be intended to be exposed as AI functions. /// This method demonstrates how to explicitly specify which methods should be exposed to the AI agent. /// /// The functions provided by this plugin. public IEnumerable AsAITools() { yield return AIFunctionFactory.Create(this.GetWeather); yield return AIFunctionFactory.Create(this.GetCurrentTime); } } internal sealed class WeatherProvider { private readonly string _weatherSummary = "cloudy with a high of 15°C"; /// /// The weather provider that returns weather information. /// /// /// Gets the weather information for the specified location. /// /// /// The weather information is hardcoded for demonstration purposes. /// In a real application, this could call a weather API to get actual weather data. /// /// The location to get the weather for. /// The weather information for the specified location. public string GetWeather(string location) { return $"The weather in {location} is {this._weatherSummary}."; } } internal sealed class CurrentTimeProvider { private readonly TimeProvider _timeProvider = TimeProvider.System; /// /// Provides the current date and time. /// /// /// This class returns the current date and time using the system's clock. /// /// /// Gets the current date and time. /// /// The location to get the current time for (not used in this implementation). /// The current date and time as a . public DateTimeOffset GetCurrentTime(string location) { return this._timeProvider.GetLocalNow(); } } }