diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx index 83cc8e6b06..ca1a7fdc8c 100644 --- a/dotnet/agent-framework-dotnet.slnx +++ b/dotnet/agent-framework-dotnet.slnx @@ -103,11 +103,11 @@ + - - + diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs index c51d345c11..3c374d799f 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/Program.cs @@ -11,14 +11,15 @@ using Microsoft.Extensions.AI; string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set."); string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini"; -const string JokerInstructions = "You are good at telling jokes."; +const string JokerInstructionsV1 = "You are good at telling jokes."; +const string JokerInstructionsV2 = "You are extremely hilarious at telling jokes."; const string JokerName = "JokerAgent"; // Get a client to create/retrieve/delete server side agents with Azure Foundry Agents. AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential()); // Define the agent you want to create. (Prompt Agent in this case) -AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions }); +AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructionsV1 }); // Azure.AI.Agents SDK creates and manages agent by name and versions. // You can create a server side agent version with the Azure.AI.Agents SDK client below. @@ -32,8 +33,8 @@ AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: // You can retrieve an AIAgent for an already created server side agent version. AIAgent jokerAgentV1 = aiProjectClient.GetAIAgent(agentVersion); -// You can also create another AIAgent version (V2) by providing the same name with a different definition. -AIAgent jokerAgentV2 = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions + "V2"); +// You can also create another AIAgent version (V2) by providing the same name with a different definition/instruction. +AIAgent jokerAgentV2 = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructionsV2); // You can also get the AIAgent latest version by just providing its name. AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName); @@ -43,11 +44,7 @@ AgentVersion latestVersion = jokerAgentLatest.GetService()!; Console.WriteLine($"Latest agent version id: {latestVersion.Id}"); // Once you have the AIAgent, you can invoke it like any other AIAgent. -AgentThread thread = jokerAgentLatest.GetNewThread(); -Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate.", thread)); - -// This will use the same thread to continue the conversation. -Console.WriteLine(await jokerAgentLatest.RunAsync("Now tell me a joke about a cat and a dog using last joke as the anchor.", thread)); +Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate.")); // Cleanup by agent name removes both agent versions created (jokerAgentV1 + jokerAgentV2). await aiProjectClient.Agents.DeleteAgentAsync(jokerAgentV1.Name); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs index bd5620ff1f..4d840d54ff 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/Program.cs @@ -26,13 +26,8 @@ AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: // You can retrieve an AIAgent for a already created server side agent version. AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion); -// Invoke the agent and output the text result. -AgentThread thread = jokerAgent.GetNewThread(); -Console.WriteLine(await jokerAgent.RunAsync("Tell me a joke about a pirate.", thread)); - // Invoke the agent with streaming support. -thread = jokerAgent.GetNewThread(); -await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate.", thread)) +await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate.")) { Console.WriteLine(update); } diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI.csproj b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI.csproj deleted file mode 100644 index 90bc94a20f..0000000000 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - Exe - net9.0 - - enable - enable - - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/OpenAPISpec.json b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/OpenAPISpec.json deleted file mode 100644 index 84715914da..0000000000 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/OpenAPISpec.json +++ /dev/null @@ -1,354 +0,0 @@ -{ - "openapi": "3.0.1", - "info": { - "title": "Github Versions API", - "version": "1.0.0" - }, - "servers": [ - { - "url": "https://api.github.com" - } - ], - "components": { - "schemas": { - "basic-error": { - "title": "Basic Error", - "description": "Basic Error", - "type": "object", - "properties": { - "message": { - "type": "string" - }, - "documentation_url": { - "type": "string" - }, - "url": { - "type": "string" - }, - "status": { - "type": "string" - } - } - }, - "label": { - "title": "Label", - "description": "Color-coded labels help you categorize and filter your issues (just like labels in Gmail).", - "type": "object", - "properties": { - "id": { - "description": "Unique identifier for the label.", - "type": "integer", - "format": "int64", - "example": 208045946 - }, - "node_id": { - "type": "string", - "example": "MDU6TGFiZWwyMDgwNDU5NDY=" - }, - "url": { - "description": "URL for the label", - "example": "https://api.github.com/repositories/42/labels/bug", - "type": "string", - "format": "uri" - }, - "name": { - "description": "The name of the label.", - "example": "bug", - "type": "string" - }, - "description": { - "description": "Optional description of the label, such as its purpose.", - "type": "string", - "example": "Something isn't working", - "nullable": true - }, - "color": { - "description": "6-character hex code, without the leading #, identifying the color", - "example": "FFFFFF", - "type": "string" - }, - "default": { - "description": "Whether this label comes by default in a new repository.", - "type": "boolean", - "example": true - } - }, - "required": [ - "id", - "node_id", - "url", - "name", - "description", - "color", - "default" - ] - }, - "tag": { - "title": "Tag", - "description": "Tag", - "type": "object", - "properties": { - "name": { - "type": "string", - "example": "v0.1" - }, - "commit": { - "type": "object", - "properties": { - "sha": { - "type": "string" - }, - "url": { - "type": "string", - "format": "uri" - } - }, - "required": [ - "sha", - "url" - ] - }, - "zipball_url": { - "type": "string", - "format": "uri", - "example": "https://github.com/octocat/Hello-World/zipball/v0.1" - }, - "tarball_url": { - "type": "string", - "format": "uri", - "example": "https://github.com/octocat/Hello-World/tarball/v0.1" - }, - "node_id": { - "type": "string" - } - }, - "required": [ - "name", - "node_id", - "commit", - "zipball_url", - "tarball_url" - ] - } - }, - "examples": { - "label-items": { - "value": [ - { - "id": 208045946, - "node_id": "MDU6TGFiZWwyMDgwNDU5NDY=", - "url": "https://api.github.com/repos/octocat/Hello-World/labels/bug", - "name": "bug", - "description": "Something isn't working", - "color": "f29513", - "default": true - }, - { - "id": 208045947, - "node_id": "MDU6TGFiZWwyMDgwNDU5NDc=", - "url": "https://api.github.com/repos/octocat/Hello-World/labels/enhancement", - "name": "enhancement", - "description": "New feature or request", - "color": "a2eeef", - "default": false - } - ] - }, - "tag-items": { - "value": [ - { - "name": "v0.1", - "commit": { - "sha": "c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc", - "url": "https://api.github.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc" - }, - "zipball_url": "https://github.com/octocat/Hello-World/zipball/v0.1", - "tarball_url": "https://github.com/octocat/Hello-World/tarball/v0.1", - "node_id": "MDQ6VXNlcjE=" - } - ] - } - }, - "parameters": { - "owner": { - "name": "owner", - "description": "The account owner of the repository. The name is not case sensitive.", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - "repo": { - "name": "repo", - "description": "The name of the repository without the `.git` extension. The name is not case sensitive.", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - "per-page": { - "name": "per_page", - "description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\"", - "in": "query", - "schema": { - "type": "integer", - "default": 30 - } - }, - "page": { - "name": "page", - "description": "The page number of the results to fetch. For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\"", - "in": "query", - "schema": { - "type": "integer", - "default": 1 - } - } - }, - "responses": { - "not_found": { - "description": "Resource not found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/basic-error" - } - } - } - } - }, - "headers": { - "link": { - "example": "; rel=\"next\", ; rel=\"last\"", - "schema": { - "type": "string" - } - } - } - }, - "paths": { - "/repos/{owner}/{repo}/tags": { - "get": { - "summary": "List repository tags", - "description": "", - "tags": [ - "repos" - ], - "operationId": "repos/list-tags", - "externalDocs": { - "description": "API method documentation", - "url": "https://docs.github.com/rest/repos/repos#list-repository-tags" - }, - "parameters": [ - { - "$ref": "#/components/parameters/owner" - }, - { - "$ref": "#/components/parameters/repo" - }, - { - "$ref": "#/components/parameters/per-page" - }, - { - "$ref": "#/components/parameters/page" - } - ], - "responses": { - "200": { - "description": "Response", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/tag" - } - }, - "examples": { - "default": { - "$ref": "#/components/examples/tag-items" - } - } - } - }, - "headers": { - "Link": { - "$ref": "#/components/headers/link" - } - } - } - }, - "x-github": { - "githubCloudOnly": false, - "enabledForGitHubApps": true, - "category": "repos", - "subcategory": "repos" - } - } - }, - "/repos/{owner}/{repo}/labels": { - "get": { - "summary": "List labels for a repository", - "description": "Lists all labels for a repository.", - "tags": [ - "issues" - ], - "operationId": "issues/list-labels-for-repo", - "externalDocs": { - "description": "API method documentation", - "url": "https://docs.github.com/rest/issues/labels#list-labels-for-a-repository" - }, - "parameters": [ - { - "$ref": "#/components/parameters/owner" - }, - { - "$ref": "#/components/parameters/repo" - }, - { - "$ref": "#/components/parameters/per-page" - }, - { - "$ref": "#/components/parameters/page" - } - ], - "responses": { - "200": { - "description": "Response", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/label" - } - }, - "examples": { - "default": { - "$ref": "#/components/examples/label-items" - } - } - } - }, - "headers": { - "Link": { - "$ref": "#/components/headers/link" - } - } - }, - "404": { - "$ref": "#/components/responses/not_found" - } - }, - "x-github": { - "githubCloudOnly": false, - "enabledForGitHubApps": true, - "category": "issues", - "subcategory": "labels" - } - } - } - } -} \ No newline at end of file diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/Program.cs deleted file mode 100644 index f9540d1725..0000000000 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/Program.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. - -// This sample demonstrates how to use an agent with function tools provided via an OpenAPI spec. -// It uses functionality from Semantic Kernel to parse the OpenAPI spec and create function tools to use with the Agent Framework Agent. - -using Azure.AI.Projects; -using Azure.Identity; -using Microsoft.Agents.AI; -using Microsoft.Extensions.AI; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Plugins.OpenApi; - -string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set."); -string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini"; - -// Load the OpenAPI Spec from a file. -KernelPlugin plugin = await OpenApiKernelPluginFactory.CreateFromOpenApiAsync("github", "OpenAPISpec.json"); - -// Convert the Semantic Kernel plugin to Agent Framework function tools. -// This requires a dummy Kernel instance, since KernelFunctions cannot execute without one. -Kernel kernel = new(); -List tools = plugin.Select(x => x.WithKernel(kernel)).Cast().ToList(); - -const string AssistantInstructions = "You are a helpful assistant that can query GitHub repositories."; -const string AssistantName = "GitHubAssistant"; - -// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents. -AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential()); - -// Create AIAgent directly -AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: tools); - -// Run the agent with the OpenAPI function tools. -AgentThread thread = agent.GetNewThread(); -Console.WriteLine(await agent.RunAsync("Please list the names, colors and descriptions of all the labels available in the microsoft/agent-framework repository on github.", thread)); - -// Cleanup by agent name removes the agent version created. -await aiProjectClient.Agents.DeleteAgentAsync(agent.Name); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/README.md b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/README.md deleted file mode 100644 index 68096e495f..0000000000 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Using Function Tools from OpenAPI Specifications - -This sample demonstrates how to create function tools from an OpenAPI specification and use them with AI agents. - -## What this sample demonstrates - -- Loading OpenAPI specifications from files -- Converting OpenAPI specifications to Semantic Kernel plugins -- Converting Semantic Kernel plugins to AI function tools -- Using OpenAPI-based function tools with AI agents -- Managing agent lifecycle (creation and deletion) - -## Prerequisites - -Before you begin, ensure you have the following prerequisites: - -- .NET 8.0 SDK or later -- Azure Foundry service endpoint and deployment configured -- Azure CLI installed and authenticated (for Azure credential authentication) - -**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively). - -Set the following environment variables: - -```powershell -$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint -$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini -``` - -## Run the sample - -Navigate to the FoundryAgents sample directory and run: - -```powershell -cd dotnet/samples/GettingStarted/FoundryAgents -dotnet run --project .\FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI -``` - -## Expected behavior - -The sample will: - -1. Load the OpenAPI specification from OpenAPISpec.json (GitHub API) -2. Convert the OpenAPI spec to Semantic Kernel plugins -3. Create an agent named "GitHubAssistant" with the OpenAPI-based function tools -4. Run the agent with a prompt to query GitHub repositories -5. The agent will invoke the appropriate OpenAPI function tools to retrieve data -6. Clean up resources by deleting the agent - diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/FoundryAgents_Step03.1_UsingFunctionTools.csproj b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/FoundryAgents_Step03_UsingFunctionTools.csproj similarity index 100% rename from dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/FoundryAgents_Step03.1_UsingFunctionTools.csproj rename to dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/FoundryAgents_Step03_UsingFunctionTools.csproj diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/Program.cs similarity index 59% rename from dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/Program.cs rename to dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/Program.cs index e2af503905..38c5a15d75 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/Program.cs @@ -26,18 +26,26 @@ AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential( AITool tool = AIFunctionFactory.Create(GetWeather); // Create AIAgent directly -AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [tool]); +var newAgent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [tool]); + +// Getting an already existing agent by name with tools. +/* + * IMPORTANT: Since agents that are stored in the server only know the definition of the function tools (JSON Schema), + * you need to provided all invocable function tools when retrieving the agent so it can invoke them automatically. + * If no invocable tools are provided, the function calling needs to handled manually. + */ +var existingAgent = await aiProjectClient.GetAIAgentAsync(name: AssistantName, tools: [tool]); // Non-streaming agent interaction with function tools. -AgentThread thread = agent.GetNewThread(); -Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", thread)); +AgentThread thread = existingAgent.GetNewThread(); +Console.WriteLine(await existingAgent.RunAsync("What is the weather like in Amsterdam?", thread)); // Streaming agent interaction with function tools. -thread = agent.GetNewThread(); -await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("What is the weather like in Amsterdam?", thread)) +thread = existingAgent.GetNewThread(); +await foreach (AgentRunResponseUpdate update in existingAgent.RunStreamingAsync("What is the weather like in Amsterdam?", thread)) { Console.WriteLine(update); } // Cleanup by agent name removes the agent version created. -await aiProjectClient.Agents.DeleteAgentAsync(agent.Name); +await aiProjectClient.Agents.DeleteAgentAsync(existingAgent.Name); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/README.md b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/README.md similarity index 100% rename from dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03.1_UsingFunctionTools/README.md rename to dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/README.md diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs index bd72a2c940..1b51d210cf 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/Program.cs @@ -25,7 +25,7 @@ const string AssistantName = "WeatherAssistant"; // Get a client to create/retrieve/delete server side agents with Azure Foundry Agents. AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential()); -ApprovalRequiredAIFunction approvalTool = new(AIFunctionFactory.Create(GetWeather)); +ApprovalRequiredAIFunction approvalTool = new(AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather))); // Create AIAgent directly AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [approvalTool]); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Assets/walkway.jpg b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Assets/walkway.jpg new file mode 100644 index 0000000000..13ef1e1840 Binary files /dev/null and b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Assets/walkway.jpg differ diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/FoundryAgents_Step10_UsingImages.csproj b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/FoundryAgents_Step10_UsingImages.csproj index d0cd81c352..1d423b22bc 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/FoundryAgents_Step10_UsingImages.csproj +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/FoundryAgents_Step10_UsingImages.csproj @@ -16,5 +16,11 @@ + + + + Always + + diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs index 52ee408a25..a799fe46fb 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/Program.cs @@ -8,7 +8,7 @@ using Microsoft.Agents.AI; using Microsoft.Extensions.AI; string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set."); -string deploymentName = System.Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o"; +string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o"; const string VisionInstructions = "You are a helpful agent that can analyze images"; const string VisionName = "VisionAgent"; @@ -21,7 +21,7 @@ AIAgent agent = aiProjectClient.CreateAIAgent(name: VisionName, model: deploymen ChatMessage message = new(ChatRole.User, [ new TextContent("What do you see in this image?"), - new UriContent("https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg", "image/jpeg") + new DataContent(File.ReadAllBytes("assets/walkway.jpg"), "image/jpeg") ]); AgentThread thread = agent.GetNewThread(); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs index 0a70ca76df..0f6f6ef2d9 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/Program.cs @@ -55,7 +55,7 @@ AgentRunResponse response = await agentOption1.RunAsync("I need to solve the equ // AgentRunResponse response = await agentOption2.RunAsync("I need to solve the equation sin(x) + x^2 = 42"); // Get the CodeInterpreterToolCallContent -CodeInterpreterToolCallContent? toolCallContent = response.Messages.SelectMany(m => m.Contents).OfType().SingleOrDefault(); +CodeInterpreterToolCallContent? toolCallContent = response.Messages.SelectMany(m => m.Contents).OfType().FirstOrDefault(); if (toolCallContent?.Inputs is not null) { DataContent? codeInput = toolCallContent.Inputs.OfType().FirstOrDefault(); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs index cb621275ea..05fb39bbf4 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/Program.cs @@ -15,8 +15,8 @@ internal sealed class Program { private static async Task Main(string[] args) { - string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set."); - string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "computer-use-preview"; + string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set."); + string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "computer-use-preview"; // Get a client to create/retrieve/delete server side agents with Azure Foundry Agents. AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential()); diff --git a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/README.md b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/README.md index 6b7f27aaf3..94ddf6b269 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/README.md +++ b/dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/README.md @@ -24,8 +24,8 @@ Before you begin, ensure you have the following prerequisites: Set the following environment variables: ```powershell -$env:AZURE_OPENAI_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint -$env:AZURE_OPENAI_DEPLOYMENT_NAME="computer-use-preview" # Optional, defaults to computer-use-preview +$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint +$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="computer-use-preview" # Optional, defaults to computer-use-preview ``` ## Run the sample diff --git a/dotnet/samples/GettingStarted/FoundryAgents/README.md b/dotnet/samples/GettingStarted/FoundryAgents/README.md index e1007473b2..c5d027d8d7 100644 --- a/dotnet/samples/GettingStarted/FoundryAgents/README.md +++ b/dotnet/samples/GettingStarted/FoundryAgents/README.md @@ -25,8 +25,7 @@ Before you begin, ensure you have the following prerequisites: |[Basics](./FoundryAgents_Step01.1_Basics/)|This sample demonstrates how to create and manage AI agents with versioning| |[Running a simple agent](./FoundryAgents_Step01.2_Running/)|This sample demonstrates how to create and run a basic Foundry agent| |[Multi-turn conversation](./FoundryAgents_Step02_MultiturnConversation/)|This sample demonstrates how to implement a multi-turn conversation with a Foundry agent| -|[Using function tools](./FoundryAgents_Step03.1_UsingFunctionTools/)|This sample demonstrates how to use function tools with a Foundry agent| -|[Using OpenAPI function tools](./FoundryAgents_Step03.2_UsingFunctionTools_FromOpenAPI/)|This sample demonstrates how to create function tools from an OpenAPI spec and use them with a Foundry agent| +|[Using function tools](./FoundryAgents_Step03_UsingFunctionTools/)|This sample demonstrates how to use function tools with a Foundry agent| |[Using function tools with approvals](./FoundryAgents_Step04_UsingFunctionToolsWithApprovals/)|This sample demonstrates how to use function tools where approvals require human in the loop approvals before execution| |[Structured output](./FoundryAgents_Step05_StructuredOutput/)|This sample demonstrates how to use structured output with a Foundry agent| |[Persisted conversations](./FoundryAgents_Step06_PersistedConversations/)|This sample demonstrates how to persist conversations and reload them later|