{"id":532,"date":"2025-09-12T08:16:08","date_gmt":"2025-09-12T08:16:08","guid":{"rendered":"https:\/\/codingwithramin.com\/?p=532"},"modified":"2026-08-17T13:46:01","modified_gmt":"2026-08-17T13:46:01","slug":"beyond-manual-indexing-building-intelligent-sharepoint-agents-part-2-implementation","status":"publish","type":"post","link":"https:\/\/codingwithramin.com\/?p=532","title":{"rendered":"Building Intelligent SharePoint Agents &#8211; Part 2: Implementation"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In<a href=\"https:\/\/codingwithramin.com\/?p=518\" data-type=\"link\" data-id=\"https:\/\/codingwithramin.com\/?p=518\"> Part 1<\/a>, we explored the fundamental shift from manual SharePoint indexing to Azure AI Foundry&#8217;s SharePoint grounding tool. We covered the challenges of traditional approaches, the power of Microsoft 365 Copilot API, and the cost considerations for enterprise adoption.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This part is the build: connecting a SharePoint site, wiring the tool into a .NET agent, and testing it end to end.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before diving into implementation, ensure you have the following ready:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure subscription with access to Microsoft Foundry (the rebrand of Azure AI Foundry; both names still show up in the docs and SDKs)<\/li>\n\n\n\n<li>Microsoft 365 Copilot license, $30\/user\/month, for every developer and end user who&#8217;ll query the agent. If your users don&#8217;t have Copilot licenses, Microsoft&#8217;s pay-as-you-go option (also preview) covers that instead<\/li>\n\n\n\n<li>Foundry User RBAC role for all developers and end users (Microsoft renamed this role from Azure AI User; permissions are unchanged)<\/li>\n\n\n\n<li>READ access to the target SharePoint sites, plus their site URLs<\/li>\n\n\n\n<li>Admin access to configure connections, if your organization requires it<\/li>\n\n\n\n<li>.NET 8 or later, Visual Studio 2022 or VS Code. .NET 8&#8217;s mainstream support ends November 10, 2026, so if you&#8217;re starting a new project, target .NET 10 instead<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Set up the SharePoint connection<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you haven&#8217;t set up an Azure AI Foundry Project yet, please refer to steps 1 and 2 in my first blog post: &#8220;<a href=\"https:\/\/codingwithramin.com\/?p=493\">Migrating from Bing Search APIs to Azure OpenAI Agent with Grounding Bing Search<\/a>&#8220;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Navigate to &#8220;<strong>Connected Resources<\/strong>&#8221; in your AI Foundry project<\/li>\n\n\n\n<li>Click &#8220;<strong>Add Connection<\/strong>&#8220;<\/li>\n\n\n\n<li>Select &#8220;<strong>SharePoint<\/strong>&#8221; as the connection type<\/li>\n\n\n\n<li>Enter your target site URL and give it a Connection name<\/li>\n\n\n\n<li>Select &#8220;<strong>Add connection<\/strong>&#8220;<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"628\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-11-1024x628.png\" alt=\"\" class=\"wp-image-535\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-11-1024x628.png 1024w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-11-300x184.png 300w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-11-768x471.png 768w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-11-769x471.png 769w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-11.png 1400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Troubleshooting Tip:<\/strong> If the connection fails, confirm your Azure AI service has permission to reach SharePoint through your organization&#8217;s Microsoft 365 tenant.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Set up the .NET project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now for the .NET side: wiring these agents into an actual application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A note on the code below: it targets the <strong>Azure.AI.Agents.Persistent<\/strong> package, the preview SDK current when this series was first published in September 2025. Microsoft&#8217;s SharePoint tool documentation has since moved to a different package (<strong>Azure.AI.Projects<\/strong>, with <strong>SharepointPreviewTool <\/strong>and the Responses API).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The pattern here (look up a connection, wrap it in a tool definition) still maps directly. Check the current Microsoft Learn SharePoint tool page for exact class names before you drop this into a new project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 Configuration Setup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Update <strong>appsettings.json<\/strong> and add SharePoint to the agents section:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">JSON<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"AzureAI\": {\n    \"ConnectionString\": \"https:\/\/yourproject.services.ai.azure.com\/api\/projects\/yourproject\"\n  },\n  \"AzureOpenAI\": {\n    \"Endpoint\": \"https:\/\/your-ai-foundry-resource.openai.azure.com\",\n    \"ApiKey\": \"your-api-key-or-use-managed-identity\",\n    \"DeploymentName\": \"gpt-4o-deployment\"\n  },\n  \"Agents\": [\n    {\n      \"Name\": \"SharePoint Knowledge Agent\",\n      \"Description\": \"Enterprise knowledge assistant with SharePoint access\",\n      \"Instructions\": \"You are a knowledgeable assistant with access to enterprise SharePoint content. When users ask questions, search through connected SharePoint sites to provide accurate, current information based on official company documents. Always cite specific documents and respect user permissions.\",\n      \"Deployment\": \"gpt-4o-deployment\",\n      \"Tools\": &#91;\n        {\n          \"ToolType\": \"SharePointGrounding\",\n          \"ConnectionName\": \"MainSharePointConnection\"\n        }\n      &#93;\n    },\n    {\n      \"Name\": \"Web Search Agent\",\n      \"Description\": \"External information research assistant\",\n      \"Instructions\": \"You are a research assistant that searches the web for current information. Use Bing search to find relevant, up-to-date information and provide accurate responses with proper citations.\",\n      \"Deployment\": \"gpt-4o-deployment\",\n      \"Tools\": &#91;\n        {\n          \"ToolType\": \"BingGroundingSearch\",\n          \"ConnectionName\": \"BingSearchConnection\"\n        }\n      &#93;\n    },\n    {\n      \"Name\": \"Hybrid Research Agent\",\n      \"Description\": \"Combined internal and external research specialist\",\n      \"Instructions\": \"You are a comprehensive research assistant with access to both internal SharePoint content and external web information. Always check internal sources first for company-specific information, then supplement with external research as needed. Clearly distinguish between internal and external sources.\",\n      \"Deployment\": \"gpt-4o-deployment\",\n      \"Tools\": &#91;\n        {\n          \"ToolType\": \"SharePointGrounding\",\n          \"ConnectionName\": \"MainSharePointConnection\"\n        },\n        {\n          \"ToolType\": \"BingGroundingSearch\",\n          \"ConnectionName\": \"BingSearchConnection\"\n        }\n      &#93;\n    }\n  ]\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;AzureAI&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;ConnectionString&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/yourproject.services.ai.azure.com\/api\/projects\/yourproject&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;AzureOpenAI&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;Endpoint&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/your-ai-foundry-resource.openai.azure.com&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;ApiKey&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;your-api-key-or-use-managed-identity&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;DeploymentName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;gpt-4o-deployment&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;Agents&quot;<\/span><span style=\"color: #D4D4D4\">: [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;SharePoint Knowledge Agent&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Enterprise knowledge assistant with SharePoint access&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Instructions&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;You are a knowledgeable assistant with access to enterprise SharePoint content. When users ask questions, search through connected SharePoint sites to provide accurate, current information based on official company documents. Always cite specific documents and respect user permissions.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Deployment&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;gpt-4o-deployment&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Tools&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ToolType&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;SharePointGrounding&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ConnectionName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;MainSharePointConnection&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Web Search Agent&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;External information research assistant&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Instructions&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;You are a research assistant that searches the web for current information. Use Bing search to find relevant, up-to-date information and provide accurate responses with proper citations.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Deployment&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;gpt-4o-deployment&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Tools&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ToolType&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;BingGroundingSearch&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ConnectionName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;BingSearchConnection&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Hybrid Research Agent&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Combined internal and external research specialist&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Instructions&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;You are a comprehensive research assistant with access to both internal SharePoint content and external web information. Always check internal sources first for company-specific information, then supplement with external research as needed. Clearly distinguish between internal and external sources.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Deployment&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;gpt-4o-deployment&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;Tools&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ToolType&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;SharePointGrounding&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ConnectionName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;MainSharePointConnection&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ToolType&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;BingGroundingSearch&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;ConnectionName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;BingSearchConnection&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  ]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.2 Agent Service Implementation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The agent service sits between your application and Azure AI Foundry. Here are the pieces that matter:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>private async Task&lt;ToolDefinition?> CreateToolDefinitionAsync(ToolsOptions tool)\n{\n\ttry\n\t{\n\t\treturn tool.ToolType switch\n\t\t{\n\t\t\t\"SharePointGrounding\" => await CreateSharePointToolAsync(tool),\n\t\t\t\"BingGroundingSearch\" => await CreateBingSearchToolAsync(tool),\n\t\t\t\"CustomBingGroundingSearch\" => await CreateCustomBingSearchToolAsync(tool),\n\t\t\t_ => throw new NotSupportedException($\"Tool type '{tool.ToolType}' is not supported\")\n\t\t};\n\t}\n\tcatch (Exception ex)\n\t{\n\t\t_logger.LogError(ex, \"Failed to create tool definition for {ToolType} with connection {ConnectionName}\",\n\t\t\ttool.ToolType, tool.ConnectionName);\n\t\treturn null;\n\t}\n}\n\nprivate async Task&lt;ToolDefinition> CreateSharePointToolAsync(ToolsOptions tool)\n{\n\tvar connection = await GetConnectionByNameAsync(tool.ConnectionName);\n\tif (connection?.Id == null)\n\t{\n\t\tthrow new InvalidOperationException($\"SharePoint connection '{tool.ConnectionName}' not found or invalid\");\n\t}\n\n\t_logger.LogInformation(\"Creating SharePoint grounding tool with connection: {ConnectionName}\",\n\t\ttool.ConnectionName);\n\t\n\treturn new SharepointToolDefinition(\n\t\tnew SharepointGroundingToolParameters(connection.Id)\n\t);\n}\n\nprivate async Task&lt;ToolDefinition> CreateBingSearchToolAsync(ToolsOptions tool)\n{\n\tvar connection = await GetConnectionByNameAsync(tool.ConnectionName);\n\tif (connection?.Id == null)\n\t{\n\t\tthrow new InvalidOperationException($\"Bing Search connection '{tool.ConnectionName}' not found or invalid\");\n\t}\n\n\treturn new BingGroundingToolDefinition(\n\t\tnew BingGroundingSearchToolParameters(\n\t\t\t&#91;new BingGroundingSearchConfiguration(connection.Id)&#93;\n\t\t)\n\t);\n}\n\nprivate async Task&lt;ToolDefinition> CreateCustomBingSearchToolAsync(ToolsOptions tool)\n{\n\tvar connection = await GetConnectionByNameAsync(tool.ConnectionName);\n\tif (connection?.Id == null)\n\t{\n\t\tthrow new InvalidOperationException($\"Custom Bing Search connection '{tool.ConnectionName}' not found or invalid\");\n\t}\n\n\tvar configuration = new BingCustomSearchConfiguration(\n\t\tconnection.Id,\n\t\ttool.ConfigurationName ?? \"default\")\n\t{\n\t\tCount = 5,\n\t\tSetLang = \"en\",\n\t\tMarket = \"en-us\"\n\t};\n\n\treturn new BingCustomSearchToolDefinition(\n\t\tnew BingCustomSearchToolParameters(&#91;configuration&#93;)\n\t);\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Task<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ToolDefinition<\/span><span style=\"color: #D4D4D4\">?&gt; <\/span><span style=\"color: #DCDCAA\">CreateToolDefinitionAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">ToolsOptions<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">try<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ToolType<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">switch<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">&quot;SharePointGrounding&quot;<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">CreateSharePointToolAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">&quot;BingGroundingSearch&quot;<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">CreateBingSearchToolAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">&quot;CustomBingGroundingSearch&quot;<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">CreateCustomBingSearchToolAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #569CD6\">_<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #C586C0\">throw<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">NotSupportedException<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;Tool type &#39;{<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">ToolType<\/span><span style=\"color: #CE9178\">}&#39; is not supported&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t};<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4EC9B0\">Exception<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Failed to create tool definition for {ToolType} with connection {ConnectionName}&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ToolType<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Task<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ToolDefinition<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">CreateSharePointToolAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">ToolsOptions<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">GetConnectionByNameAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\">?.<\/span><span style=\"color: #9CDCFE\">Id<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">throw<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">InvalidOperationException<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;SharePoint connection &#39;{<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #CE9178\">}&#39; not found or invalid&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogInformation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Creating SharePoint grounding tool with connection: {ConnectionName}&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">SharepointToolDefinition<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">SharepointGroundingToolParameters<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Id<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Task<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ToolDefinition<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">CreateBingSearchToolAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">ToolsOptions<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">GetConnectionByNameAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\">?.<\/span><span style=\"color: #9CDCFE\">Id<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">throw<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">InvalidOperationException<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;Bing Search connection &#39;{<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #CE9178\">}&#39; not found or invalid&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingGroundingToolDefinition<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingGroundingSearchToolParameters<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t&#91;<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingGroundingSearchConfiguration<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Id<\/span><span style=\"color: #D4D4D4\">)&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Task<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ToolDefinition<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">CreateCustomBingSearchToolAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">ToolsOptions<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">GetConnectionByNameAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\">?.<\/span><span style=\"color: #9CDCFE\">Id<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">throw<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">InvalidOperationException<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;Custom Bing Search connection &#39;{<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #CE9178\">}&#39; not found or invalid&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingCustomSearchConfiguration<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">connection<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Id<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConfigurationName<\/span><span style=\"color: #D4D4D4\"> ?? <\/span><span style=\"color: #CE9178\">&quot;default&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">5<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">SetLang<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;en&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">Market<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;en-us&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingCustomSearchToolDefinition<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingCustomSearchToolParameters<\/span><span style=\"color: #D4D4D4\">(&#91;<\/span><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>CreateToolDefinitionAsync Method<\/strong> is the factory method. It pattern-matches on <code>tool.ToolType<\/code> to build the tool the config asks for.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>CreateSharePointToolAsync Method<\/strong> handles the SharePoint-specific part. It looks up the connection by name and wraps it in a SharepointToolDefinition, which is what the AI service uses to reach your SharePoint content.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both methods check the connection before creating anything and throw a specific exception if it&#8217;s missing. I&#8217;d rather fail at startup with a clear error than have an agent silently come up with no working tools.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Putting tool creation behind this service means adding a new tool type later is a new case in the switch statement, not a rewrite of the agent logic.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.3 Agent wrapper class<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The agent wrapper sits around the core agent and handles initialization, cleanup, and resource management. Here&#8217;s the method I added for connection validation:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>public async Task&lt;bool> ValidateConnectionsAsync()\n        {\n            try\n            {\n                if (_agentOptions.Tools == null || _agentOptions.Tools.Count == 0)\n                {\n                    _logger.LogInformation(\"Agent '{AgentName}' has no tools to validate\", _agentOptions.Name);\n                    return true;\n                }\n\n                var allValid = true;\n                foreach (var tool in _agentOptions.Tools)\n                {\n                    var isValid = await _agentService.ValidateConnectionAsync(tool.ConnectionName);\n                    if (!isValid)\n                    {\n                        _logger.LogWarning(\"Invalid connection '{ConnectionName}' for tool '{ToolType}' in agent '{AgentName}'\", \n                            tool.ConnectionName, tool.ToolType, _agentOptions.Name);\n                        allValid = false;\n                    }\n                }\n\n                return allValid;\n            }\n            catch (Exception ex)\n            {\n                _logger.LogError(ex, \"Failed to validate connections for agent '{AgentName}'\", _agentOptions.Name);\n                return false;\n            }\n        }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Task<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">bool<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">ValidateConnectionsAsync<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">try<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">_agentOptions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Tools<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">_agentOptions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Tools<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogInformation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Agent &#39;{AgentName}&#39; has no tools to validate&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_agentOptions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">allValid<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">foreach<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_agentOptions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Tools<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isValid<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_agentService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ValidateConnectionAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">isValid<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogWarning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Invalid connection &#39;{ConnectionName}&#39; for tool &#39;{ToolType}&#39; in agent &#39;{AgentName}&#39;&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                            <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ConnectionName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">tool<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ToolType<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_agentOptions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #9CDCFE\">allValid<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">allValid<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4EC9B0\">Exception<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Failed to validate connections for agent &#39;{AgentName}&#39;&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_agentOptions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Connection Validation<\/strong>: Before an agent becomes active, it validates that all required connections are working properly. This prevents agents from failing during user interactions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Error Handling<\/strong>: The wrapper includes comprehensive error handling and logging, making it easier to diagnose issues in production environments.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.4 Main Application<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The main application brings everything together:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7\">C#<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>using Azure.AI.Agents.Persistent;\nusing BingGroundingAgent;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.Extensions.Logging;\nusing System.ComponentModel.DataAnnotations;\n\nvar builder = Host.CreateApplicationBuilder(args);\n\nvar configuration = new ConfigurationBuilder()\n    .SetBasePath(Directory.GetCurrentDirectory())\n    .AddJsonFile(\"appsettings.json\", optional: false, reloadOnChange: true)\n    .AddEnvironmentVariables()\n    .Build();\n\nbuilder.Services.AddSingleton&lt;IConfiguration>(configuration);\nbuilder.Services.AddSingleton&lt;AgentService>();\n\n\/\/ Register agents from configuration\nvar agentsConfig = new AgentsConfiguration();\nconfiguration.GetSection(\"Agents\").Bind(agentsConfig.Agents);\n\nif (agentsConfig.Agents.Count == 0)\n{\n\tConsole.WriteLine(\"No agents configured. Please check your appsettings.json file.\");\n\treturn;\n}\n\n\/\/ Validate agent configurations\nvar validAgents = new List&lt;AgentOptions>();\nforeach (var agentConfig in agentsConfig.Agents)\n{\n\tvar validationResults = new List&lt;ValidationResult>();\n\tvar validationContext = new ValidationContext(agentConfig);\n\n\tif (Validator.TryValidateObject(agentConfig, validationContext, validationResults, true))\n\t{\n\t\tvalidAgents.Add(agentConfig);\n\t}\n\telse\n\t{\n\t\tvar errors = string.Join(\", \", validationResults.Select(vr => vr.ErrorMessage));\n\t\tConsole.WriteLine($\"Invalid configuration for agent '{agentConfig.Name}': {errors}\");\n\t}\n}\n\nif (validAgents.Count == 0)\n{\n\tConsole.WriteLine(\"No valid agents found. Please check your configuration.\");\n\treturn;\n}\n\n\/\/ Register each agent as a named service\nforeach (var agentConfig in agentsConfig.Agents)\n{\n    var agentType = agentConfig.Name; \/\/ Fallback to name if type is not set\n    builder.Services.AddKeyedSingleton&lt;AzureAgent>(\n        agentType,\n        (provider, key) =>\n            new AzureAgent(\n                provider.GetRequiredService&lt;ILogger&lt;AzureAgent>>(),\n                provider.GetRequiredService&lt;AgentService>(),\n                agentConfig\n            )\n    );\n}\n\nbuilder.Services.AddLogging(logging =>\n{\n    logging.AddConsole();\n    logging.SetMinimumLevel(LogLevel.Information);\n});\n\nvar host = builder.Build();\nvar logger = host.Services.GetRequiredService&lt;ILogger&lt;Program>>();\n\n\/\/ Get available agents from configuration\nvar availableAgents = new AgentsConfiguration();\nconfiguration.GetSection(\"Agents\").Bind(availableAgents.Agents);\n\n\/\/ Let user select which agent to use\nConsole.WriteLine(\"Available agents:\");\nfor (int i = 0; i &lt; availableAgents.Agents.Count; i++)\n{\n    var agent = availableAgents.Agents&#91;i&#93;;\n    Console.WriteLine($\"{i + 1}. {agent.Name}\");\n}\n\nConsole.Write(\"Select an agent (1-{0}): \", availableAgents.Agents.Count);\nvar selection = Console.ReadLine();\n\nif (\n    !int.TryParse(selection, out int agentIndex)\n    || agentIndex &lt; 1\n    || agentIndex > availableAgents.Agents.Count\n)\n{\n    logger.LogError(\"Invalid agent selection\");\n    return;\n}\n\nvar selectedAgentConfig = availableAgents.Agents&#91;agentIndex - 1&#93;;\nvar agentKey = selectedAgentConfig.Name;\nvar selectedAgent = host.Services.GetRequiredKeyedService&lt;AzureAgent>(agentKey);\n\ntry\n{\n    logger.LogInformation(\"Initializing {AgentName}...\", selectedAgentConfig.Name);\n    await selectedAgent.InitializeAsync();\n\n    while (true)\n    {\n        Console.Write(\"\\nYou: \");\n        var input = Console.ReadLine();\n        if (string.IsNullOrEmpty(input) || input.ToLower() == \"exit\")\n            break;\n\n        logger.LogInformation(\"Processing query: {Query}\", input);\n\n        Console.Write(\"Assistant: \");\n        await foreach (var update in await selectedAgent.ProcessQueryAsync(input))\n        {\n            try\n            {\n                if (update.UpdateKind == StreamingUpdateReason.MessageUpdated)\n                {\n                    if (update is MessageContentUpdate messageContent)\n                    {\n                        \/\/ Filter out citation markers and special characters\n                        var text = messageContent.Text;\n                        if (!string.IsNullOrEmpty(text))\n                        {\n                            Console.Write(text);\n                        }\n                    }\n                }\n            }\n            catch (Exception updateEx)\n            {\n                logger.LogWarning(updateEx, \"Error processing streaming update\");\n            }\n        }\n\n        \/\/ Output references (citations)\n        await selectedAgent.DisplayCitationsAsync();\n    }\n}\ncatch (Exception ex)\n{\n    logger.LogError(ex, \"An error occurred: {Message}\", ex.Message);\n}\n\nlogger.LogInformation(\"Application completed\");\nawait host.StopAsync();\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Azure<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">AI<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Agents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Persistent<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">BingGroundingAgent<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Microsoft<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Extensions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Configuration<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Microsoft<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Extensions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">DependencyInjection<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Microsoft<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Extensions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Hosting<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Microsoft<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Extensions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Logging<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">ComponentModel<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">DataAnnotations<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">builder<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Host<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">CreateApplicationBuilder<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">args<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">ConfigurationBuilder<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">SetBasePath<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">Directory<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetCurrentDirectory<\/span><span style=\"color: #D4D4D4\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">AddJsonFile<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;appsettings.json&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">optional<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">reloadOnChange<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">AddEnvironmentVariables<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">Build<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">builder<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Services<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">AddSingleton<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">IConfiguration<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">builder<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Services<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">AddSingleton<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">AgentService<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Register agents from configuration<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentsConfig<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">AgentsConfiguration<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetSection<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Agents&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">Bind<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">agentsConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">agentsConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;No agents configured. Please check your appsettings.json file.&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Validate agent configurations<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validAgents<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">AgentOptions<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">foreach<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentsConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validationResults<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ValidationResult<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">validationContext<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">ValidationContext<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">Validator<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryValidateObject<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">validationContext<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">validationResults<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">validAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">errors<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Join<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;, &quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">validationResults<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Select<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">vr<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">vr<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ErrorMessage<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;Invalid configuration for agent &#39;{<\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #CE9178\">}&#39;: {<\/span><span style=\"color: #9CDCFE\">errors<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">validAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;No valid agents found. Please check your configuration.&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Register each agent as a named service<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">foreach<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentsConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentType<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #6A9955\">\/\/ Fallback to name if type is not set<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">builder<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Services<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">AddKeyedSingleton<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">AzureAgent<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">agentType<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        (<\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">key<\/span><span style=\"color: #D4D4D4\">) =&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">AzureAgent<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetRequiredService<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ILogger<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">AzureAgent<\/span><span style=\"color: #D4D4D4\">&gt;&gt;(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetRequiredService<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">AgentService<\/span><span style=\"color: #D4D4D4\">&gt;(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">agentConfig<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">builder<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Services<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">AddLogging<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">logging<\/span><span style=\"color: #D4D4D4\"> =&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">logging<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">AddConsole<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">logging<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SetMinimumLevel<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">LogLevel<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Information<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">});<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">host<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">builder<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Build<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">host<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Services<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetRequiredService<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">ILogger<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">Program<\/span><span style=\"color: #D4D4D4\">&gt;&gt;();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Get available agents from configuration<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">AgentsConfiguration<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetSection<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Agents&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">Bind<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Let user select which agent to use<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Available agents:&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agent<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #CE9178\"> <\/span><span style=\"color: #D4D4D4\">+<\/span><span style=\"color: #CE9178\"> <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #CE9178\">}. {<\/span><span style=\"color: #9CDCFE\">agent<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Select an agent (1-{0}): &quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">selection<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadLine<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    !<\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryParse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">selection<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentIndex<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    || <\/span><span style=\"color: #9CDCFE\">agentIndex<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #B5CEA8\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    || <\/span><span style=\"color: #9CDCFE\">agentIndex<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Invalid agent selection&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">selectedAgentConfig<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">availableAgents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Agents<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #9CDCFE\">agentIndex<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentKey<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">selectedAgentConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">selectedAgent<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">host<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Services<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetRequiredKeyedService<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">AzureAgent<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><span style=\"color: #9CDCFE\">agentKey<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">try<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogInformation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Initializing {AgentName}...&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">selectedAgentConfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Name<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">selectedAgent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">InitializeAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">You: &quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadLine<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">IsNullOrEmpty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">) || <\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ToLower<\/span><span style=\"color: #D4D4D4\">() == <\/span><span style=\"color: #CE9178\">&quot;exit&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">break<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogInformation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Processing query: {Query}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Assistant: &quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">foreach<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">update<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">selectedAgent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ProcessQueryAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">try<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #DCDCAA\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">update<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">UpdateKind<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">StreamingUpdateReason<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">MessageUpdated<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #DCDCAA\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">update<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">MessageContentUpdate<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">messageContent<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">                        \/\/ Filter out citation markers and special characters<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #9CDCFE\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">messageContent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #DCDCAA\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">IsNullOrEmpty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                            <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">Exception<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">updateEx<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogWarning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">updateEx<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Error processing streaming update&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">        \/\/ Output references (citations)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">selectedAgent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">DisplayCitationsAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #4EC9B0\">Exception<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;An error occurred: {Message}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">ex<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Message<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogInformation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Application completed&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">host<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">StopAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The program reads agent configs from <strong>appsettings.json<\/strong> and validates each one with data annotations before anything runs, so a typo in the config file fails at startup instead of mid-conversation. It lets you pick which agent to talk to and streams the response as <strong>MessageContentUpdate <\/strong>events arrive.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Citations print after the response finishes, not inline, where they&#8217;d break up the text.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Test SharePoint agent<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run the application and select the SharePoint agent:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"421\" height=\"127\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-12.png\" alt=\"\" class=\"wp-image-536\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-12.png 421w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-12-300x90.png 300w\" sizes=\"auto, (max-width: 421px) 100vw, 421px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Try queries like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What documents are available in SharePoint?<\/li>\n\n\n\n<li>Find information about [specific topic in your SharePoint]<\/li>\n\n\n\n<li>Show me the latest [document type] from [SharePoint site]<\/li>\n\n\n\n<li>List key points from document [document name]<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"249\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-14-1024x249.png\" alt=\"\" class=\"wp-image-538\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-14-1024x249.png 1024w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-14-300x73.png 300w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-14-768x186.png 768w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-14-769x187.png 769w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-14.png 1471w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"205\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-15-1024x205.png\" alt=\"\" class=\"wp-image-539\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-15-1024x205.png 1024w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-15-300x60.png 300w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-15-768x154.png 768w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-15-769x154.png 769w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2025\/07\/image-15.png 1441w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Security Considerations<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Your SharePoint agents touch sensitive corporate information, so the security model is worth understanding upfront.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Data in transit: all traffic between your application, Azure AI Foundry, and SharePoint uses TLS encryption.<\/li>\n\n\n\n<li>Permission inheritance: agents automatically respect SharePoint permissions. Users only see content they&#8217;re already authorized to access.<\/li>\n\n\n\n<li>No data storage: Azure AI Foundry doesn&#8217;t store your SharePoint content. It queries live, on every request.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>SharePoint Site Optimization:<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Limit scope: connect only the SharePoint sites that contain relevant information.<\/li>\n\n\n\n<li>Organize content: well-structured sites with clear metadata improve search accuracy.<\/li>\n\n\n\n<li>Regular cleanup: archive or delete outdated documents to keep results relevant.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ve successfully built a powerful SharePoint agent that transform how your organization accesses and utilizes knowledge. These agents eliminate the traditional barriers of manual indexing while maintaining security and permissions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The impact on your organization:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time Savings<\/strong>: Users find information in seconds instead of hours<\/li>\n\n\n\n<li><strong>Better Decisions<\/strong>: Access to comprehensive, current information<\/li>\n\n\n\n<li><strong>Knowledge Democratization<\/strong>: Everyone can access organizational knowledge easily<\/li>\n\n\n\n<li><strong>Reduced IT Overhead<\/strong>: No search infrastructure to maintain<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Before you open this to real users, run a permission test: sign in as two users with different access to the same site, ask both the same question, and confirm the one without permission gets no citation back. Microsoft&#8217;s own SharePoint tool documentation recommends exactly this check before rollout, and it matters more than watching a demo query return an answer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Source Code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The complete source code for this series is on GitHub:\u00a0<a href=\"https:\/\/github.com\/AhmadiRamin\/azure-ai-agents\">GitHub Repository Link<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Part 1, we explored the fundamental shift from manual SharePoint indexing to Azure AI Foundry&#8217;s SharePoint grounding tool. We covered the challenges of traditional approaches, the power of Microsoft 365 Copilot API, and the cost considerations for enterprise adoption. This part is the build: connecting a SharePoint site, wiring the tool into a .NET agent, and testing it end to end. Prerequisites Before diving into implementation, ensure you have the following ready: Set up&hellip;<\/p>\n","protected":false},"author":1,"featured_media":542,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55,5],"tags":[61,49,51,9,59],"class_list":["post-532","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-microsoft-azure","tag-agents","tag-ai","tag-ai-foundry","tag-azure","tag-azure-ai-agent"],"_links":{"self":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/532","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=532"}],"version-history":[{"count":11,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/532\/revisions"}],"predecessor-version":[{"id":820,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/532\/revisions\/820"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/media\/542"}],"wp:attachment":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=532"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=532"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=532"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}