{"id":600,"date":"2026-03-31T14:47:33","date_gmt":"2026-03-31T14:47:33","guid":{"rendered":"https:\/\/codingwithramin.com\/?p=600"},"modified":"2026-08-18T20:27:39","modified_gmt":"2026-08-18T20:27:39","slug":"building-a-sharepoint-agent-that-remembers-combining-memory-sharepoint-grounding","status":"publish","type":"post","link":"https:\/\/codingwithramin.com\/?p=600","title":{"rendered":"Building a SharePoint agent that remembers: combining memory and SharePoint grounding"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In <a href=\"https:\/\/codingwithramin.com\/?p=592\">Part 1<\/a>, we built a Foundry agent with long-term memory that could remember user preferences, roles, and context across sessions without any custom embedding pipelines. If you haven&#8217;t read that post, start there. This one builds directly on top of that code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Memory alone is useful. It just doesn&#8217;t go very far on its own. Knowing a user prefers bullet-point summaries or works in finance is helpful context, but it doesn&#8217;t change what the agent can actually do. It still can&#8217;t answer questions about your company&#8217;s policies, find the document someone shared last week, or pull up the latest project brief.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s where SharePoint grounding comes in. In my earlier series on <a href=\"https:\/\/codingwithramin.com\/?p=518\">Building Intelligent SharePoint Agents<\/a>, I walked through how the SharePoint tool in Foundry Agent Service grounds agent responses in your actual enterprise content, with automatic indexing and permission-aware retrieval built in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This post combines both capabilities into a single agent: one that searches your SharePoint content intelligently and remembers what each user has asked about before, their role, and their preferences. That&#8217;s the difference between a search tool and an assistant that actually knows you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why combine memory and SharePoint grounding?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Consider what each capability does on its own.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SharePoint grounding alone lets the agent search your enterprise documents and give accurate, permission-aware answers, but every conversation starts from zero. A user in legal who asks about compliance policies every morning has to re-establish context each time: the agent doesn&#8217;t know they&#8217;re a lawyer, and it can&#8217;t adapt its response style to how they like information delivered.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Memory alone remembers who the user is and what they care about, but it can&#8217;t touch any enterprise content. It&#8217;s a knowledgeable assistant locked out of your company&#8217;s own documents.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Combine the two and you get something actually useful. The agent knows this user works in legal, prefers detailed responses with clause references, and asked about the data privacy policy last week. When they come back and ask &#8220;any updates on what we discussed?&#8221;, it searches SharePoint for changes to that specific policy and answers in the format this user prefers. No context re-establishment needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This post builds on the code from Part 1. Make sure you have:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>From Part 1:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A working Foundry project with the memory store code from the <a href=\"https:\/\/github.com\/AhmadiRamin\/azure-ai-foundry-agent-memory-dotnet\">GitHub repository<\/a><\/li>\n\n\n\n<li>The MemoryService class (unchanged from Part 1)<\/li>\n\n\n\n<li>Chat model (e.g., GPT 5.4) and embedding model (e.g., text-embedding-3-small) deployed<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Additional for Part 2:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A Microsoft 365 Copilot license for every user who&#8217;ll interact with the agent, required by the SharePoint Retrieval API, or the pay-as-you-go model enabled<\/li>\n\n\n\n<li>A SharePoint site with documents you want the agent to search<\/li>\n\n\n\n<li>READ access to the target SharePoint site for your users<\/li>\n\n\n\n<li>A SharePoint connection configured in your Foundry project<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Setting up the SharePoint connection<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you followed my earlier <a href=\"https:\/\/codingwithramin.com\/?p=518\">SharePoint agents series<\/a>, you&#8217;ll already have this configured. If not:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In your Foundry project, navigate to <strong>Connected Resources<\/strong><\/li>\n\n\n\n<li>Click <strong>Add Connection<\/strong> <\/li>\n\n\n\n<li>Select <strong>SharePoint<\/strong> as the connection type<\/li>\n\n\n\n<li>Enter your target site URL (e.g., https:\/\/contoso.sharepoint.com\/sites\/policies)<\/li>\n\n\n\n<li>Give it a connection name (e.g., MainSharePointConnection)<\/li>\n\n\n\n<li>Save the connection and note down the <strong>Connection ID<\/strong><\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><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\" style=\"width:590px;height:auto\" 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<h2 class=\"wp-block-heading\">Updated configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Update your <strong>appsettings.json<\/strong> to include the SharePoint connection details alongside the existing memory configuration:<\/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  \"Foundry\": {\n    \"ProjectEndpoint\": \"&lt;your-project-id>\",\n    \"ApiVersion\": \"2025-11-15-preview\",\n    \"AgentApiVersion\": \"2025-11-15-preview\",\n    \"TenantId\": \"&lt;your-tenant-id>\"\n  },\n  \"Models\": {\n    \"ChatModel\": \"gpt-4o\",\n    \"EmbeddingModel\": \"text-embedding-3-small\"\n  },\n  \"Memory\": {\n    \"StoreName\": \"enterprise_memory_store\",\n    \"StoreDescription\": \"Long-term memory for enterprise SharePoint assistant\",\n    \"UserProfileDetails\": \"Capture the user's role, department, document preferences, frequently accessed topics, and SharePoint sites they commonly reference. Avoid sensitive data such as financial details, credentials, and personal identifiers.\",\n    \"UpdateDelaySeconds\": 60\n  },\n  \"SharePoint\": {\n    \"ConnectionName\": \"MainSharePointConnection\"\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;Foundry&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;ProjectEndpoint&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;&lt;your-project-id&gt;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;ApiVersion&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;2025-11-15-preview&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;AgentApiVersion&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;2025-11-15-preview&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;TenantId&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;&lt;your-tenant-id&gt;&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;Models&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;ChatModel&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;gpt-4o&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;EmbeddingModel&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;text-embedding-3-small&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;Memory&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;StoreName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;enterprise_memory_store&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;StoreDescription&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Long-term memory for enterprise SharePoint assistant&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;UserProfileDetails&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Capture the user&#39;s role, department, document preferences, frequently accessed topics, and SharePoint sites they commonly reference. Avoid sensitive data such as financial details, credentials, and personal identifiers.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">&quot;UpdateDelaySeconds&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">60<\/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;SharePoint&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><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Two things changed from Part 1:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>UserProfileDetails<\/strong>: Now asks for SharePoint-specific context too: frequently accessed topics and the sites a user commonly references. That tells the memory system to pay attention to the kinds of documents people ask about, which improves the relevance of future SharePoint searches<\/li>\n\n\n\n<li><strong>SharePoint section<\/strong>: Holding the connection name. The full connection ID gets resolved at runtime through the Connections API.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">The SharePoint memory agent<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the core of Part 2: extending the MemoryAgent from Part 1 to include SharePoint grounding. The key change is that the agent now carries two tools in its definition, memory_search_preview and sharepoint_grounding_preview.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I built a new SharePointMemoryAgent class instead of modifying MemoryAgent directly. That way you can keep both: the memory-only agent for scenarios that don&#8217;t need SharePoint, and the combined agent for the full enterprise experience.<\/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.Identity;\nusing FoundrySharePointMemoryAgent;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.Logging;\nusing System.Net.Http.Headers;\nusing System.Text;\nusing System.Text.Json;\n\nnamespace FoundrySharePointMemoryAgent;\n\npublic class SharePointMemoryAgent\n{\n\tprivate readonly MemoryStoreService _memoryService;\n\tprivate readonly IConfiguration _configuration;\n\tprivate readonly ILogger&lt;SharePointMemoryAgent> _logger;\n\tprivate readonly HttpClient _httpClient;\n\tprivate readonly DefaultAzureCredential _credential;\n\n\tprivate readonly string _endpoint;\n\tprivate readonly string _storeName;\n\tprivate readonly string _agentApiVersion;\n\n\tprivate string? _agentName;\n\tprivate string? _conversationId;\n\tprivate string _scope = \"dev_user_001\";\n\tprivate string? _lastUpdateId;\n\n\tpublic SharePointMemoryAgent(\n\t\tMemoryStoreService memoryService,\n\t\tHttpClient httpClient,\n\t\tIConfiguration configuration,\n\t\tILogger&lt;SharePointMemoryAgent> logger)\n\t{\n\t\t_memoryService = memoryService;\n\t\t_httpClient = httpClient;\n\t\t_configuration = configuration;\n\t\t_logger = logger;\n\n\t\t_endpoint = _configuration&#91;\"Foundry:ProjectEndpoint\"&#93;\n\t\t\t?? throw new InvalidOperationException(\"Foundry project endpoint not configured\");\n\t\t_storeName = _configuration&#91;\"Memory:StoreName\"&#93; ?? \"enterprise_memory_store\";\n\t\t_agentApiVersion = _configuration&#91;\"Foundry:AgentApiVersion\"&#93; ?? \"2025-11-15-preview\";\n\n\t\tvar tenantId = _configuration&#91;\"Foundry:TenantId\"&#93;;\n\t\t_credential = string.IsNullOrEmpty(tenantId)\n\t\t\t? new DefaultAzureCredential()\n\t\t\t: new DefaultAzureCredential(new DefaultAzureCredentialOptions { TenantId = tenantId });\n\t}\n\n\tprivate async Task&lt;string> SetAuthHeaderAsync()\n\t{\n\t\tvar tokenResult = await _credential.GetTokenAsync(\n\t\t\tnew Azure.Core.TokenRequestContext(&#91;\"https:\/\/ai.azure.com\/.default\"&#93;));\n\t\t_httpClient.DefaultRequestHeaders.Authorization =\n\t\t\tnew AuthenticationHeaderValue(\"Bearer\", tokenResult.Token);\n\t\treturn tokenResult.Token;\n\t}\n\n\tprivate static string ResolveScopeFromToken(string jwt)\n\t{\n\t\tvar parts = jwt.Split('.');\n\t\tif (parts.Length &lt; 2) return \"dev_user_001\";\n\n\t\tvar payload = parts&#91;1&#93;;\n\t\tpayload = payload.Replace('-', '+').Replace('_', '\/');\n\t\tpayload = payload.PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');\n\n\t\tvar json = Encoding.UTF8.GetString(Convert.FromBase64String(payload));\n\t\tvar doc = JsonDocument.Parse(json);\n\n\t\tvar tid = doc.RootElement.TryGetProperty(\"tid\", out var tidProp) ? tidProp.GetString() : null;\n\t\tvar oid = doc.RootElement.TryGetProperty(\"oid\", out var oidProp) ? oidProp.GetString() : null;\n\n\t\treturn (!string.IsNullOrEmpty(tid) &amp;&amp; !string.IsNullOrEmpty(oid))\n\t\t\t? $\"{tid}_{oid}\" : \"dev_user_001\";\n\t}\n\n\tprivate async Task&lt;string?> ResolveSharePointConnectionIdAsync()\n\t{\n\t\tvar connectionName = _configuration&#91;\"SharePoint:ConnectionName\"&#93;;\n\t\tif (string.IsNullOrEmpty(connectionName))\n\t\t{\n\t\t\t_logger.LogWarning(\"SharePoint connection name not configured\");\n\t\t\treturn null;\n\t\t}\n\n\t\tawait SetAuthHeaderAsync();\n\n\t\tvar response = await _httpClient.GetAsync(\n\t\t\t$\"{_endpoint}\/connections\/{connectionName}?api-version={_agentApiVersion}\");\n\n\t\tif (!response.IsSuccessStatusCode)\n\t\t{\n\t\t\tvar error = await response.Content.ReadAsStringAsync();\n\t\t\t_logger.LogError(\"Failed to resolve SharePoint connection: {Error}\", error);\n\t\t\treturn null;\n\t\t}\n\n\t\tvar result = await response.Content.ReadAsStringAsync();\n\t\tvar doc = JsonDocument.Parse(result);\n\n\t\tif (doc.RootElement.TryGetProperty(\"id\", out var idProp))\n\t\t{\n\t\t\tvar connectionId = idProp.GetString();\n\t\t\t_logger.LogInformation(\"Resolved SharePoint connection: {Id}\", connectionId);\n\t\t\treturn connectionId;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate async Task&lt;bool> TryGetExistingAgentAsync(string agentName)\n\t{\n\t\tvar response = await _httpClient.GetAsync(\n\t\t\t$\"{_endpoint}\/agents\/{agentName}?api-version={_agentApiVersion}\");\n\n\t\tif (response.IsSuccessStatusCode)\n\t\t{\n\t\t\t_agentName = agentName;\n\t\t\t_logger.LogInformation(\"Agent '{Name}' already exists, reusing\", _agentName);\n\t\t\treturn true;\n\t\t}\n\n\t\tif (response.StatusCode == System.Net.HttpStatusCode.NotFound)\n\t\t\treturn false;\n\n\t\tvar error = await response.Content.ReadAsStringAsync();\n\t\t_logger.LogWarning(\"Unexpected response checking agent existence: {Status} - {Error}\",\n\t\t\tresponse.StatusCode, error);\n\t\treturn false;\n\t}\n\n\tpublic async Task InitializeAsync()\n\t{\n\t\tvar token = await SetAuthHeaderAsync();\n\t\t_scope = ResolveScopeFromToken(token);\n\t\t_logger.LogInformation(\"Using memory scope: {Scope}\", _scope);\n\n\t\tvar created = await _memoryService.CreateMemoryStoreAsync(_storeName);\n\t\tif (!created)\n\t\t\tthrow new InvalidOperationException(\"Failed to create or verify memory store\");\n\n\t\tvar scopeHash = Math.Abs(_scope.GetHashCode()).ToString();\n\t\tvar agentName = $\"SharePointMemoryAgent\";\n\n\t\tif (await TryGetExistingAgentAsync(agentName))\n\t\t\treturn;\n\n\t\tvar sharepointConnectionId = await ResolveSharePointConnectionIdAsync();\n\n\t\tawait SetAuthHeaderAsync();\n\n\t\tvar chatModel = _configuration&#91;\"Models:ChatModel\"&#93; ?? \"gpt-4o\";\n\t\tvar updateDelay = int.Parse(_configuration&#91;\"Memory:UpdateDelaySeconds\"&#93; ?? \"5\");\n\n\t\tvar tools = new List&lt;object>\n\t\t{\n\t\t\tnew\n\t\t\t{\n\t\t\t\ttype = \"memory_search_preview\",\n\t\t\t\tmemory_store_name = _storeName,\n\t\t\t\tscope = _scope,\n\t\t\t\tupdate_delay = updateDelay\n\t\t\t}\n\t\t};\n\n\t\tif (!string.IsNullOrEmpty(sharepointConnectionId))\n\t\t{\n\t\t\ttools.Add(new\n\t\t\t{\n\t\t\t\ttype = \"sharepoint_grounding_preview\",\n\t\t\t\tsharepoint_grounding_preview = new\n\t\t\t\t{\n\t\t\t\t\tproject_connections = new[]\n\t\t\t\t\t{\n\t\t\t\t\t\tnew { project_connection_id = sharepointConnectionId }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t_logger.LogInformation(\"SharePoint grounding tool added to agent\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_logger.LogWarning(\"SharePoint not available - running with memory only\");\n\t\t}\n\n\t\tvar agentPayload = new\n\t\t{\n\t\t\tname = agentName,\n\t\t\tdefinition = new\n\t\t\t{\n\t\t\t\tkind = \"prompt\",\n\t\t\t\tmodel = chatModel,\n\t\t\t\tinstructions = @\"You are a knowledgeable enterprise assistant with two capabilities:\n\n1. Long-term memory: You remember information about each user across conversations --\n   their role, department, preferences, and what they've asked about before.\n\n2. SharePoint search: You can search enterprise documents stored in SharePoint to\n   provide accurate, up-to-date answers grounded in official company content.\n\nWhen responding:\n- Use what you know about the user from memory to tailor your answers. If you know\n  they work in legal, emphasise compliance aspects. If they prefer summaries, be concise.\n- When you find relevant SharePoint documents, cite them naturally. Explain what you\n  found and why it's relevant to this user's question.\n- If a user asks about something from a previous session, use that context naturally.\n  Don't announce that you're recalling from memory.\n- If you're unsure whether stored context is still accurate, confirm with the user.\n- If a user shares new information about themselves, acknowledge it naturally.\",\n\t\t\t\ttools\n\t\t\t}\n\t\t};\n\n\t\tvar content = new StringContent(\n\t\t\tJsonSerializer.Serialize(agentPayload),\n\t\t\tEncoding.UTF8, \"application\/json\");\n\n\t\tvar response = await _httpClient.PostAsync(\n\t\t\t$\"{_endpoint}\/agents?api-version={_agentApiVersion}\", content);\n\n\t\tif (response.IsSuccessStatusCode)\n\t\t{\n\t\t\tvar result = await response.Content.ReadAsStringAsync();\n\t\t\tvar doc = JsonDocument.Parse(result);\n\t\t\t_agentName = doc.RootElement.GetProperty(\"name\").GetString();\n\t\t\t_logger.LogInformation(\"Agent '{Name}' initialized with memory + SharePoint\", _agentName);\n\t\t\treturn;\n\t\t}\n\n\t\tif (response.StatusCode == System.Net.HttpStatusCode.Conflict)\n\t\t{\n\t\t\t_agentName = agentName;\n\t\t\t_logger.LogInformation(\"Agent '{Name}' already exists, reusing\", _agentName);\n\t\t\treturn;\n\t\t}\n\n\t\tvar err = await response.Content.ReadAsStringAsync();\n\t\tthrow new InvalidOperationException($\"Failed to create agent: {err}\");\n\t}\n\n\tpublic async Task StartNewConversationAsync()\n\t{\n\t\tawait SetAuthHeaderAsync();\n\n\t\tvar response = await _httpClient.PostAsync(\n\t\t\t$\"{_endpoint}\/openai\/v1\/conversations\",\n\t\t\tnew StringContent(\"{}\", Encoding.UTF8, \"application\/json\"));\n\n\t\tif (!response.IsSuccessStatusCode)\n\t\t{\n\t\t\tvar error = await response.Content.ReadAsStringAsync();\n\t\t\tthrow new InvalidOperationException(\n\t\t\t\t$\"Failed to create conversation: {response.StatusCode} - {error}\");\n\t\t}\n\n\t\tvar result = await response.Content.ReadAsStringAsync();\n\t\tvar doc = JsonDocument.Parse(result);\n\t\t_conversationId = doc.RootElement.GetProperty(\"id\").GetString();\n\t\t_lastUpdateId = null;\n\t\t_logger.LogInformation(\"Started conversation: {Id}\", _conversationId);\n\n\t\t\/\/ Static retrieval: scope only (no items) \u2192 returns user_profile memories\n\t\tvar staticMemories = await _memoryService.SearchMemoriesAsync(_storeName, _scope);\n\t\t\/\/ Contextual retrieval: scope + items \u2192 returns both user_profile AND chat_summary\n\t\tvar contextualMemories = await _memoryService.SearchMemoriesAsync(\n\t\t\t_storeName, _scope, query: \"previous conversations and user information\");\n\t\tvar totalLoaded = staticMemories.Select(m => m.MemoryId)\n\t\t\t.Union(contextualMemories.Select(m => m.MemoryId)).Count();\n\t\tif (totalLoaded > 0)\n\t\t\t_logger.LogInformation(\"Loaded {Count} stored memories ({Static} user_profile, {Contextual} contextual) for this user\",\n\t\t\t\ttotalLoaded, staticMemories.Count, contextualMemories.Count);\n\t}\n\n\tpublic async Task&lt;string> SendMessageAsync(string userMessage)\n\t{\n\t\tif (_conversationId == null || _agentName == null)\n\t\t\tthrow new InvalidOperationException(\n\t\t\t\t\"Call InitializeAsync and StartNewConversationAsync first\");\n\n\t\tawait SetAuthHeaderAsync();\n\n\t\tvar payload = new\n\t\t{\n\t\t\tinput = userMessage,\n\t\t\tconversation = _conversationId,\n\t\t\tagent_reference = new\n\t\t\t{\n\t\t\t\ttype = \"agent_reference\",\n\t\t\t\tname = _agentName\n\t\t\t}\n\t\t};\n\n\t\tvar content = new StringContent(\n\t\t\tJsonSerializer.Serialize(payload),\n\t\t\tEncoding.UTF8, \"application\/json\");\n\n\t\tvar response = await _httpClient.PostAsync(\n\t\t\t$\"{_endpoint}\/openai\/v1\/responses\", content);\n\n\t\tif (!response.IsSuccessStatusCode)\n\t\t{\n\t\t\tvar error = await response.Content.ReadAsStringAsync();\n\t\t\t_logger.LogError(\"Agent response failed: {Error}\", error);\n\t\t\treturn \"Sorry, I encountered an error processing your request.\";\n\t\t}\n\n\t\tvar result = await response.Content.ReadAsStringAsync();\n\t\t_logger.LogDebug(\"Raw agent response: {Response}\", result);\n\n\t\tvar doc = JsonDocument.Parse(result);\n\n\t\tvar outputText = \"\";\n\t\tvar citations = new List&lt;string>();\n\n\t\tif (doc.RootElement.TryGetProperty(\"output\", out var output))\n\t\t{\n\t\t\tforeach (var item in output.EnumerateArray())\n\t\t\t{\n\t\t\t\tvar itemType = item.TryGetProperty(\"type\", out var typeProp)\n\t\t\t\t\t? typeProp.GetString() : null;\n\n\t\t\t\tif (itemType == \"message\" &amp;&amp; item.TryGetProperty(\"content\", out var msgContent))\n\t\t\t\t{\n\t\t\t\t\tforeach (var part in msgContent.EnumerateArray())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (part.TryGetProperty(\"text\", out var text))\n\t\t\t\t\t\t\toutputText += text.GetString();\n\n\t\t\t\t\t\tExtractAnnotationCitations(part, citations);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t\/\/ Tool result items may carry citation metadata\n\t\t\t\tif (itemType == \"tool_result\" || itemType == \"web_search_call\" ||\n\t\t\t\t\titemType == \"sharepoint_grounding_preview\")\n\t\t\t\t{\n\t\t\t\t\tExtractAnnotationCitations(item, citations);\n\n\t\t\t\t\tif (item.TryGetProperty(\"content\", out var toolContent))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var part in toolContent.EnumerateArray())\n\t\t\t\t\t\t\tExtractAnnotationCitations(part, citations);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (string.IsNullOrEmpty(outputText) &amp;&amp;\n\t\t\tdoc.RootElement.TryGetProperty(\"output_text\", out var fallback))\n\t\t\toutputText = fallback.GetString() ?? \"\";\n\n\t\t\/\/ Update memory with the conversation turn so chat_summary entries are generated\n\t\tif (!string.IsNullOrEmpty(outputText))\n\t\t{\n\t\t\t_lastUpdateId = await _memoryService.UpdateMemoriesAsync(\n\t\t\t\t_storeName, _scope, userMessage, outputText, _lastUpdateId);\n\t\t}\n\n\t\t\/\/ Deduplicate citations (same URL may appear multiple times)\n\t\tvar seen = new HashSet&lt;string>(StringComparer.OrdinalIgnoreCase);\n\t\tvar uniqueCitations = citations.Where(c => seen.Add(c)).ToList();\n\n\t\tif (uniqueCitations.Count > 0)\n\t\t{\n\t\t\toutputText += \"\\n\\nSources:\";\n\t\t\tforeach (var c in uniqueCitations) outputText += $\"\\n{c}\";\n\t\t}\n\n\t\treturn outputText;\n\t}\n\n\tprivate void ExtractAnnotationCitations(JsonElement element, List&lt;string> citations)\n\t{\n\t\tif (!element.TryGetProperty(\"annotations\", out var annotations))\n\t\t\treturn;\n\n\t\tforeach (var ann in annotations.EnumerateArray())\n\t\t{\n\t\t\tif (!ann.TryGetProperty(\"type\", out var annType))\n\t\t\t\tcontinue;\n\n\t\t\tvar type = annType.GetString();\n\n\t\t\tif (type == \"url_citation\" &amp;&amp; ann.TryGetProperty(\"url\", out var url))\n\t\t\t{\n\t\t\t\tvar title = ann.TryGetProperty(\"title\", out var t) &amp;&amp; t.GetString() is { } tStr\n\t\t\t\t\t? tStr : url.GetString();\n\t\t\t\tcitations.Add($\"  {title} - {url.GetString()}\");\n\t\t\t}\n\t\t\telse if (type == \"file_citation\" || type == \"file_path\")\n\t\t\t{\n\t\t\t\tvar fileId = ann.TryGetProperty(\"file_id\", out var fid) ? fid.GetString() : null;\n\t\t\t\tvar filename = ann.TryGetProperty(\"filename\", out var fn) ? fn.GetString() : fileId;\n\t\t\t\tif (!string.IsNullOrEmpty(filename))\n\t\t\t\t\tcitations.Add($\"  {filename}\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async Task ShowStoredMemoriesAsync()\n\t{\n\t\t\/\/ Static retrieval: scope only (no items) \u2192 returns user_profile memories\n\t\tvar staticMemories = await _memoryService.SearchMemoriesAsync(_storeName, _scope);\n\n\t\t\/\/ Contextual retrieval: scope + items \u2192 returns both user_profile AND chat_summary\n\t\tvar contextualMemories = await _memoryService.SearchMemoriesAsync(\n\t\t\t_storeName, _scope, query: \"previous conversations and user information\");\n\n\t\t\/\/ Merge, preferring contextual results and deduplicating by MemoryId\n\t\tvar seen = new HashSet&lt;string>();\n\t\tvar all = new List&lt;MemoryItem>();\n\t\tforeach (var m in contextualMemories.Concat(staticMemories))\n\t\t{\n\t\t\tif (seen.Add(m.MemoryId))\n\t\t\t\tall.Add(m);\n\t\t}\n\n\t\tif (all.Count == 0)\n\t\t{\n\t\t\tConsole.WriteLine(\"  (No memories stored yet for this user)\");\n\t\t\treturn;\n\t\t}\n\n\t\tforeach (var m in all)\n\t\t\tConsole.WriteLine($\"  &#91;{m.MemoryType}&#93; {m.Content}\");\n\t}\n\n\tpublic async Task ClearMemoriesAsync()\n\t{\n\t\tawait _memoryService.DeleteScopeAsync(_storeName, _scope);\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: #C586C0\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Azure<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Identity<\/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\">FoundrySharePointMemoryAgent<\/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\">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\">Net<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Http<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Headers<\/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\">Text<\/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\">Text<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Json<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">namespace<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">FoundrySharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">SharePointMemoryAgent<\/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\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">MemoryStoreService<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">IConfiguration<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">ILogger<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">SharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">HttpClient<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">DefaultAzureCredential<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_credential<\/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: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">readonly<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_agentApiVersion<\/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: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #9CDCFE\">_conversationId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;dev_user_001&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #569CD6\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #9CDCFE\">_lastUpdateId<\/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: #569CD6\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #4EC9B0\">MemoryStoreService<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">memoryService<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #4EC9B0\">HttpClient<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">httpClient<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #4EC9B0\">IConfiguration<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #4EC9B0\">ILogger<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">SharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">logger<\/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\">_memoryService<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">memoryService<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">httpClient<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">configuration<\/span><span style=\"color: #D4D4D4\">;<\/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: #9CDCFE\">logger<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;Foundry:ProjectEndpoint&quot;<\/span><span style=\"color: #D4D4D4\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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;Foundry project endpoint not configured&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;Memory:StoreName&quot;<\/span><span style=\"color: #D4D4D4\">&#93; ?? <\/span><span style=\"color: #CE9178\">&quot;enterprise_memory_store&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_agentApiVersion<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;Foundry:AgentApiVersion&quot;<\/span><span style=\"color: #D4D4D4\">&#93; ?? <\/span><span style=\"color: #CE9178\">&quot;2025-11-15-preview&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/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\">tenantId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;Foundry:TenantId&quot;<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_credential<\/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\">tenantId<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t? <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">DefaultAzureCredential<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t: <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">DefaultAzureCredential<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">DefaultAzureCredentialOptions<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">TenantId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">tenantId<\/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\">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: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">SetAuthHeaderAsync<\/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: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tokenResult<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_credential<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetTokenAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Azure<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Core<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">TokenRequestContext<\/span><span style=\"color: #D4D4D4\">(&#91;<\/span><span style=\"color: #CE9178\">&quot;https:\/\/ai.azure.com\/.default&quot;<\/span><span style=\"color: #D4D4D4\">&#93;));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">DefaultRequestHeaders<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Authorization<\/span><span style=\"color: #D4D4D4\"> =<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">AuthenticationHeaderValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Bearer&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">tokenResult<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Token<\/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: #9CDCFE\">tokenResult<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Token<\/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\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">static<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ResolveScopeFromToken<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">jwt<\/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: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">parts<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">jwt<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Split<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;.&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">parts<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Length<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;dev_user_001&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/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\">payload<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">parts<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Replace<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;-&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;+&#39;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">Replace<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;_&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;\/&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">PadRight<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Length<\/span><span style=\"color: #D4D4D4\"> + (<\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Length<\/span><span style=\"color: #D4D4D4\"> % <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">) % <\/span><span style=\"color: #B5CEA8\">4<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&#39;=&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">json<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Encoding<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">UTF8<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">Convert<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">FromBase64String<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">));<\/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\">doc<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JsonDocument<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">json<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">tid<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;tid&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tidProp<\/span><span style=\"color: #D4D4D4\">) ? <\/span><span style=\"color: #9CDCFE\">tidProp<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/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\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">oid<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;oid&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">oidProp<\/span><span style=\"color: #D4D4D4\">) ? <\/span><span style=\"color: #9CDCFE\">oidProp<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">() : <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/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\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">IsNullOrEmpty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">tid<\/span><span style=\"color: #D4D4D4\">) &amp;&amp; !<\/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\">oid<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t? <\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">tid<\/span><span style=\"color: #CE9178\">}_{<\/span><span style=\"color: #9CDCFE\">oid<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #CE9178\">&quot;dev_user_001&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\">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: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">?&gt; <\/span><span style=\"color: #DCDCAA\">ResolveSharePointConnectionIdAsync<\/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: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">connectionName<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;SharePoint:ConnectionName&quot;<\/span><span style=\"color: #D4D4D4\">&#93;;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">connectionName<\/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\t\t<\/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;SharePoint connection name not configured&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SetAuthHeaderAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/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\">response<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #CE9178\">}\/connections\/{<\/span><span style=\"color: #9CDCFE\">connectionName<\/span><span style=\"color: #CE9178\">}?api-version={<\/span><span style=\"color: #9CDCFE\">_agentApiVersion<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">IsSuccessStatusCode<\/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\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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: #CE9178\">&quot;Failed to resolve SharePoint connection: {Error}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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\t}<\/span><\/span>\n<span class=\"line\"><\/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\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line cbp-see-more-line cbp-see-more-transition\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JsonDocument<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;id&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">idProp<\/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\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">connectionId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">idProp<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\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;Resolved SharePoint connection: {Id}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">connectionId<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">connectionId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><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: #569CD6\">bool<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">TryGetExistingAgentAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agentName<\/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: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #CE9178\">}\/agents\/{<\/span><span style=\"color: #9CDCFE\">agentName<\/span><span style=\"color: #CE9178\">}?api-version={<\/span><span style=\"color: #9CDCFE\">_agentApiVersion<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">IsSuccessStatusCode<\/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\t\t<\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">agentName<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\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;Agent &#39;{Name}&#39; already exists, reusing&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/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\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">StatusCode<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Net<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">HttpStatusCode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">NotFound<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/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>\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\">error<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/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\">LogWarning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Unexpected response checking agent existence: {Status} - {Error}&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">StatusCode<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">error<\/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\">false<\/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\">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\"> <\/span><span style=\"color: #DCDCAA\">InitializeAsync<\/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: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SetAuthHeaderAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">ResolveScopeFromToken<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">);<\/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\">LogInformation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Using memory scope: {Scope}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">created<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">CreateMemoryStoreAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">created<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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;Failed to create or verify memory store&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">scopeHash<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Math<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Abs<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetHashCode<\/span><span style=\"color: #D4D4D4\">()).<\/span><span style=\"color: #DCDCAA\">ToString<\/span><span style=\"color: #D4D4D4\">();<\/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\">agentName<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">$&quot;SharePointMemoryAgent&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">TryGetExistingAgentAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">agentName<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/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\">sharepointConnectionId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ResolveSharePointConnectionIdAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SetAuthHeaderAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/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\">chatModel<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;Models:ChatModel&quot;<\/span><span style=\"color: #D4D4D4\">&#93; ?? <\/span><span style=\"color: #CE9178\">&quot;gpt-4o&quot;<\/span><span style=\"color: #D4D4D4\">;<\/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\">updateDelay<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_configuration<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #CE9178\">&quot;Memory:UpdateDelaySeconds&quot;<\/span><span style=\"color: #D4D4D4\">&#93; ?? <\/span><span style=\"color: #CE9178\">&quot;5&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">tools<\/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: #569CD6\">object<\/span><span style=\"color: #D4D4D4\">&gt;<\/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: #569CD6\">new<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;memory_search_preview&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">memory_store_name<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">scope<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">update_delay<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">updateDelay<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">sharepointConnectionId<\/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\t\t<\/span><span style=\"color: #9CDCFE\">tools<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;sharepoint_grounding_preview&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">sharepoint_grounding_preview<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t<\/span><span style=\"color: #9CDCFE\">project_connections<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\">[]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">project_connection_id<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">sharepointConnectionId<\/span><span style=\"color: #D4D4D4\"> }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t});<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\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;SharePoint grounding tool added to agent&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\t<\/span><span style=\"color: #C586C0\">else<\/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: #9CDCFE\">_logger<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">LogWarning<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;SharePoint not available - running with memory only&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>\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\">agentPayload<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/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: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">agentName<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">definition<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">kind<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;prompt&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">model<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">chatModel<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">instructions<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">@&quot;You are a knowledgeable enterprise assistant with two capabilities:<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">1. Long-term memory: You remember information about each user across conversations --<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">   their role, department, preferences, and what they&#39;ve asked about before.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">2. SharePoint search: You can search enterprise documents stored in SharePoint to<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">   provide accurate, up-to-date answers grounded in official company content.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">When responding:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">- Use what you know about the user from memory to tailor your answers. If you know<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">  they work in legal, emphasise compliance aspects. If they prefer summaries, be concise.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">- When you find relevant SharePoint documents, cite them naturally. Explain what you<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">  found and why it&#39;s relevant to this user&#39;s question.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">- If a user asks about something from a previous session, use that context naturally.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">  Don&#39;t announce that you&#39;re recalling from memory.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">- If you&#39;re unsure whether stored context is still accurate, confirm with the user.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">- If a user shares new information about themselves, acknowledge it naturally.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">tools<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t};<\/span><\/span>\n<span class=\"line\"><\/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\">content<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StringContent<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">JsonSerializer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Serialize<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">agentPayload<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">Encoding<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">UTF8<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;application\/json&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">response<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">PostAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #CE9178\">}\/agents?api-version={<\/span><span style=\"color: #9CDCFE\">_agentApiVersion<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">content<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">IsSuccessStatusCode<\/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\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JsonDocument<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;name&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\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;Agent &#39;{Name}&#39; initialized with memory + SharePoint&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">StatusCode<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Net<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">HttpStatusCode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Conflict<\/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\t\t<\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">agentName<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\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;Agent &#39;{Name}&#39; already exists, reusing&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_agentName<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/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\">err<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/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;Failed to create agent: {<\/span><span style=\"color: #9CDCFE\">err<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><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\"> <\/span><span style=\"color: #DCDCAA\">StartNewConversationAsync<\/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: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SetAuthHeaderAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/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\">response<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">PostAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #CE9178\">}\/openai\/v1\/conversations&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StringContent<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;{}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Encoding<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">UTF8<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;application\/json&quot;<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">IsSuccessStatusCode<\/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\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #CE9178\">$&quot;Failed to create conversation: {<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">StatusCode<\/span><span style=\"color: #CE9178\">} - {<\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #CE9178\">}&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>\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\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/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\">doc<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JsonDocument<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_conversationId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;id&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">_lastUpdateId<\/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\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;Started conversation: {Id}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_conversationId<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\/\/ Static retrieval: scope only (no items) \u2192 returns user_profile memories<\/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\">staticMemories<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SearchMemoriesAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\/\/ Contextual retrieval: scope + items \u2192 returns both user_profile AND chat_summary<\/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\">contextualMemories<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SearchMemoriesAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">query<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;previous conversations and user information&quot;<\/span><span style=\"color: #D4D4D4\">);<\/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\">totalLoaded<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">staticMemories<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Select<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">MemoryId<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t.<\/span><span style=\"color: #DCDCAA\">Union<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">contextualMemories<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Select<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">MemoryId<\/span><span style=\"color: #D4D4D4\">)).<\/span><span style=\"color: #DCDCAA\">Count<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">totalLoaded<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\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;Loaded {Count} stored memories ({Static} user_profile, {Contextual} contextual) for this user&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">totalLoaded<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">staticMemories<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">contextualMemories<\/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: #D4D4D4\">\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><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\">string<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #DCDCAA\">SendMessageAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">userMessage<\/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\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">_conversationId<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">_agentName<\/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\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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #CE9178\">&quot;Call InitializeAsync and StartNewConversationAsync first&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SetAuthHeaderAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/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\">payload<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/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: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">userMessage<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">conversation<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_conversationId<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">agent_reference<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;agent_reference&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_agentName<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t};<\/span><\/span>\n<span class=\"line\"><\/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\">content<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StringContent<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">JsonSerializer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Serialize<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">Encoding<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">UTF8<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;application\/json&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">response<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_httpClient<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">PostAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #CE9178\">$&quot;{<\/span><span style=\"color: #9CDCFE\">_endpoint<\/span><span style=\"color: #CE9178\">}\/openai\/v1\/responses&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">content<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">IsSuccessStatusCode<\/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\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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: #CE9178\">&quot;Agent response failed: {Error}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;Sorry, I encountered an error processing your request.&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>\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\">result<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadAsStringAsync<\/span><span style=\"color: #D4D4D4\">();<\/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\">LogDebug<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Raw agent response: {Response}&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">doc<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">JsonDocument<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Parse<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">result<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/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\">outputText<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">;<\/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\">citations<\/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: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;output&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">output<\/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\t\t<\/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\">item<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">output<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">EnumerateArray<\/span><span style=\"color: #D4D4D4\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">itemType<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">item<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">typeProp<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t? <\/span><span style=\"color: #9CDCFE\">typeProp<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">() : <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">itemType<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;message&quot;<\/span><span style=\"color: #D4D4D4\"> &amp;&amp; <\/span><span style=\"color: #9CDCFE\">item<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;content&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">msgContent<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t<\/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\">part<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">msgContent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">EnumerateArray<\/span><span style=\"color: #D4D4D4\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">part<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/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\">\t\t\t\t\t\t\t<\/span><span style=\"color: #9CDCFE\">outputText<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t\t<\/span><span style=\"color: #DCDCAA\">ExtractAnnotationCitations<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">part<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">citations<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\t\t\/\/ Tool result items may carry citation metadata<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">itemType<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;tool_result&quot;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">itemType<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;web_search_call&quot;<\/span><span style=\"color: #D4D4D4\"> ||<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t<\/span><span style=\"color: #9CDCFE\">itemType<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;sharepoint_grounding_preview&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t<\/span><span style=\"color: #DCDCAA\">ExtractAnnotationCitations<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">item<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">citations<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">item<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;content&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">toolContent<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t\t<\/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\">part<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">toolContent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">EnumerateArray<\/span><span style=\"color: #D4D4D4\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t\t\t<\/span><span style=\"color: #DCDCAA\">ExtractAnnotationCitations<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">part<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">citations<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">outputText<\/span><span style=\"color: #D4D4D4\">) &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">doc<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">RootElement<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;output_text&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">fallback<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">outputText<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">fallback<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">() ?? <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\/\/ Update memory with the conversation turn so chat_summary entries are generated<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">outputText<\/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\t\t<\/span><span style=\"color: #9CDCFE\">_lastUpdateId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">UpdateMemoriesAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">userMessage<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">outputText<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_lastUpdateId<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\/\/ Deduplicate citations (same URL may appear multiple times)<\/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\">seen<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">HashSet<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">&gt;(<\/span><span style=\"color: #9CDCFE\">StringComparer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">OrdinalIgnoreCase<\/span><span style=\"color: #D4D4D4\">);<\/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\">uniqueCitations<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">citations<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Where<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">seen<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #D4D4D4\">)).<\/span><span style=\"color: #DCDCAA\">ToList<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uniqueCitations<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Count<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/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\t\t<\/span><span style=\"color: #9CDCFE\">outputText<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D7BA7D\">\\n\\n<\/span><span style=\"color: #CE9178\">Sources:&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/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\">c<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">uniqueCitations<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">outputText<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #CE9178\">$&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">{<\/span><span style=\"color: #9CDCFE\">c<\/span><span style=\"color: #CE9178\">}&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>\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\">outputText<\/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\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">void<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ExtractAnnotationCitations<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">JsonElement<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">element<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">List<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">citations<\/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\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">element<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;annotations&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">annotations<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">ann<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">annotations<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">EnumerateArray<\/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\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">ann<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">annType<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #C586C0\">continue<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">annType<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;url_citation&quot;<\/span><span style=\"color: #D4D4D4\"> &amp;&amp; <\/span><span style=\"color: #9CDCFE\">ann<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;url&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">url<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">title<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">ann<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;title&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">) &amp;&amp; <\/span><span style=\"color: #9CDCFE\">t<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">() <\/span><span style=\"color: #569CD6\">is<\/span><span style=\"color: #D4D4D4\"> { } <\/span><span style=\"color: #9CDCFE\">tStr<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t? <\/span><span style=\"color: #9CDCFE\">tStr<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #9CDCFE\">url<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">citations<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;  {<\/span><span style=\"color: #9CDCFE\">title<\/span><span style=\"color: #CE9178\">} - {<\/span><span style=\"color: #9CDCFE\">url<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #CE9178\">()}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">else<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;file_citation&quot;<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;file_path&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">fileId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">ann<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;file_id&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">fid<\/span><span style=\"color: #D4D4D4\">) ? <\/span><span style=\"color: #9CDCFE\">fid<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/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\t\t\t<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">filename<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">ann<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;filename&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">out<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">fn<\/span><span style=\"color: #D4D4D4\">) ? <\/span><span style=\"color: #9CDCFE\">fn<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">() : <\/span><span style=\"color: #9CDCFE\">fileId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/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\">filename<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t\t<\/span><span style=\"color: #9CDCFE\">citations<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;  {<\/span><span style=\"color: #9CDCFE\">filename<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t}<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><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\"> <\/span><span style=\"color: #DCDCAA\">ShowStoredMemoriesAsync<\/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: #6A9955\">\t\t\/\/ Static retrieval: scope only (no items) \u2192 returns user_profile memories<\/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\">staticMemories<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SearchMemoriesAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\/\/ Contextual retrieval: scope + items \u2192 returns both user_profile AND chat_summary<\/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\">contextualMemories<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SearchMemoriesAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">query<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;previous conversations and user information&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\t\t\/\/ Merge, preferring contextual results and deduplicating by MemoryId<\/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\">seen<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">HashSet<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">&gt;();<\/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\">all<\/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\">MemoryItem<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">m<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">contextualMemories<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Concat<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">staticMemories<\/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\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">seen<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">MemoryId<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t\t<\/span><span style=\"color: #9CDCFE\">all<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Add<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">all<\/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\">\t\t{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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;  (No memories stored yet for this user)&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/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\">m<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">all<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\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;  &#91;{<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">MemoryType<\/span><span style=\"color: #CE9178\">}&#93; {<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #CE9178\">.<\/span><span style=\"color: #9CDCFE\">Content<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><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\"> <\/span><span style=\"color: #DCDCAA\">ClearMemoriesAsync<\/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: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_memoryService<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">DeleteScopeAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_storeName<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_scope<\/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><\/code><\/pre><div class=\"cbp-see-more-container\" style=\"display:flex;flex-direction:column;align-items:center;width:100%;font-size:12px;line-height:1;position:relative;padding-top:4px;margin-bottom:-16px;height:32px\"><div style=\"background-color:#1e1e1e;height:50%;position:absolute;top:0;left:0;right:0\" aria-hidden=\"true\"><\/div><span role=\"button\" tabindex=\"0\" class=\"cbp-see-more-simple-btn cbp-see-more-simple-btn-hover\" style=\"color:#fafafa;background-color:#373737;padding:6px 14px;cursor:default;position:relative;border-radius:6px\">Expand<\/span><\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Five things changed from Part 1&#8217;s MemoryAgent:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ResolveSharePointConnectionIdAsync resolves the SharePoint connection ID from the connection name at runtime, through the Connections API. Same pattern as my earlier SharePoint agents series: configure the connection name in appsettings.json and let the code resolve the full ID. No hard-coded connection strings.<\/li>\n\n\n\n<li>The agent definition now carries two tools instead of one. The runtime picks between them on its own: ask about company content and it routes to SharePoint, bring up something personal and it pulls from memory. Often it uses both in the same turn.<\/li>\n\n\n\n<li>If the SharePoint connection can&#8217;t be resolved, the agent still runs with memory only. One tool going down shouldn&#8217;t take the whole agent with it.<\/li>\n\n\n\n<li>SendMessageAsync now parses url_citation annotations from the response. When the agent grounds an answer in a SharePoint document, these annotations say exactly which document it used.<\/li>\n\n\n\n<li>The system prompt spells out how to combine memory and search context, instead of leaving the model to work out the interaction on its own. That one change produced noticeably better answers when I tested it.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">InitializeAsync checks whether the agent already exists before building a new one, resolves the SharePoint connection, and attaches both tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Updated console application<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Program.cs changes are small: swap MemoryAgent for SharePointMemoryAgent in the DI registrations and the HttpClient setup. MemoryStoreService barely changes either. Its UpdateMemoriesAsync method picks up one new parameter for the assistant&#8217;s reply text, so chat-summary extraction captures both sides of the exchange. Nothing else in that class moves.<\/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>builder.Services.AddSingleton&lt;IConfiguration>(configuration);\nbuilder.Services.AddHttpClient&lt;MemoryStoreService>();\nbuilder.Services.AddHttpClient&lt;SharePointMemoryAgent>();\nbuilder.Services.AddSingleton&lt;MemoryStoreService>();\nbuilder.Services.AddSingleton&lt;SharePointMemoryAgent>();\n\nbuilder.Services.AddLogging(logging =>\n{\n\tlogging.AddConsole();\n});\n\nvar host = builder.Build();\nvar logger = host.Services.GetRequiredService&lt;ILogger&lt;Program>>();\nvar agent = host.Services.GetRequiredService&lt;SharePointMemoryAgent>();<\/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: #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\">AddHttpClient<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">MemoryStoreService<\/span><span style=\"color: #D4D4D4\">&gt;();<\/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\">AddHttpClient<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">SharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">&gt;();<\/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\">MemoryStoreService<\/span><span style=\"color: #D4D4D4\">&gt;();<\/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\">SharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">&gt;();<\/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\">\t<\/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>\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 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\">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\">SharePointMemoryAgent<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the combined experience<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Combining memory and SharePoint grounding shows up clearly across two sessions. I uploaded a data privacy policy document, Contoso-Data-Privacy-Policy-v3.0.docx, to SharePoint first.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"764\" height=\"434\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/04\/image-1.png\" alt=\"\" class=\"wp-image-604\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/04\/image-1.png 764w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/04\/image-1-300x170.png 300w\" sizes=\"auto, (max-width: 764px) 100vw, 764px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Session 1<\/strong>, establishing context and asking about documents:<\/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\">TSX<\/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>You: I'm a compliance officer at Contoso. I'm responsible for data privacy\n     regulations. I prefer concise summaries with document section references.\n\nAssistant: Got it! I can help you find and review compliance-related content\n           from your SharePoint sites. What would you like to look into?\n\nYou: What does our current data privacy policy say about third-party data sharing?\n\nAssistant: Based on the Contoso Data Privacy Policy (Section 4.2), third-party\n          data sharing requires written consent from the data subject and must\n          be reviewed by the compliance team before execution...\n\nSources:\n  Contoso Data Privacy Policy - https:\/\/contoso.sharepoint.com\/...\/privacy-policy.pdf<\/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: #C8C8C8\">You<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">I<\/span><span style=\"color: #CE9178\">&#39;m a compliance officer at Contoso. I&#39;<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">responsible<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">for<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">privacy<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     <\/span><span style=\"color: #9CDCFE\">regulations<\/span><span style=\"color: #D4D4D4\">. <\/span><span style=\"color: #4FC1FF\">I<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">prefer<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">concise<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">summaries<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">document<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">section<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">references<\/span><span style=\"color: #D4D4D4\">.<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">Assistant<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #9CDCFE\">Got<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">it<\/span><span style=\"color: #D4D4D4\">! <\/span><span style=\"color: #4FC1FF\">I<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">can<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">help<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">you<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">find<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">and<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">review<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">compliance<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">related<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">content<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">           <\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">your<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">SharePoint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sites<\/span><span style=\"color: #D4D4D4\">. <\/span><span style=\"color: #9CDCFE\">What<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">would<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">you<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">like<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">look<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">into<\/span><span style=\"color: #D4D4D4\">?<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">You<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #9CDCFE\">What<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">does<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">our<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">current<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">say<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">about<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">third<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">party<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sharing<\/span><span style=\"color: #D4D4D4\">?<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Assistant<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #9CDCFE\">Based<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">on<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Contoso<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Policy<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">Section<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">4.2<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">third<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">party<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sharing<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">requires<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">written<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">consent<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">subject<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">and<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">must<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">be<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">reviewed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">by<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">compliance<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">team<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">before<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">execution<\/span><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">Sources<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">Contoso<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Policy<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #C8C8C8\">https<\/span><span style=\"color: #D4D4D4\">:<\/span><span style=\"color: #6A9955\">\/\/contoso.sharepoint.com\/...\/privacy-policy.pdf<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Typing <strong>\/memories<\/strong> shows what got captured:<\/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\">TSX<\/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>Stored memories:\n  &#91;user_profile&#93; Compliance officer at Contoso, responsible for data privacy regulations\n  &#91;user_profile&#93; Prefers concise summaries with document section references\n  &#91;chat_summary&#93; User asked about third-party data sharing in the data privacy policy<\/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: #9CDCFE\">Stored<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C8C8C8\">memories<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &#91;<\/span><span style=\"color: #9CDCFE\">user_profile<\/span><span style=\"color: #D4D4D4\">&#93; <\/span><span style=\"color: #9CDCFE\">Compliance<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">officer<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">at<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Contoso<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">responsible<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">for<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">regulations<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &#91;<\/span><span style=\"color: #9CDCFE\">user_profile<\/span><span style=\"color: #D4D4D4\">&#93; <\/span><span style=\"color: #9CDCFE\">Prefers<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">concise<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">summaries<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">document<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">section<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">references<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &#91;<\/span><span style=\"color: #9CDCFE\">chat_summary<\/span><span style=\"color: #D4D4D4\">&#93; <\/span><span style=\"color: #9CDCFE\">User<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">asked<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">about<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">third<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">party<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sharing<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">policy<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For <strong>Session 2<\/strong>, I made a few edits to section 4.2 of the document and uploaded both versions to the GitHub repo. Then I typed <strong>\/new<\/strong> to start a fresh conversation:<\/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\">TSX<\/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>You: Have there been any updates to what we discussed last time?\n\nAssistant: I checked the data privacy policy documents in SharePoint. The\n          third-party data sharing section (4.2) you asked about last time\n          was last updated on March 10, 2026. The key change is that\n          third-party processors now require DPA agreements to be filed\n          with legal before any data transfer begins...\n\nSources:\n  Updated Data Privacy Policy v3.1 - https:\/\/contoso.sharepoint.com\/...\/privacy-policy-v3.1.pdf<\/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: #C8C8C8\">You<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #9CDCFE\">Have<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">there<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">been<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">any<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">updates<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">what<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">we<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">discussed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">last<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">time<\/span><span style=\"color: #D4D4D4\">?<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Assistant<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4FC1FF\">I<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">checked<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">policy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">documents<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">SharePoint<\/span><span style=\"color: #D4D4D4\">. <\/span><span style=\"color: #9CDCFE\">The<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">third<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">party<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sharing<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">section<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #B5CEA8\">4.2<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">you<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">asked<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">about<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">last<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">time<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">was<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">last<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">updated<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">on<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">March<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">10<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">2026.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">The<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">key<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">change<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">that<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">third<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">party<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">processors<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">now<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">require<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">DPA<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">agreements<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">be<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">filed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #C586C0\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">legal<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">before<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">any<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">transfer<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">begins<\/span><span style=\"color: #D4D4D4\">...<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C8C8C8\">Sources<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">Updated<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Data<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Privacy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Policy<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">v3<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> - <\/span><span style=\"color: #C8C8C8\">https<\/span><span style=\"color: #D4D4D4\">:<\/span><span style=\"color: #6A9955\">\/\/contoso.sharepoint.com\/...\/privacy-policy-v3.1.pdf<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The agent knew this was the same compliance officer who&#8217;d asked about third-party data sharing, and it went straight to SharePoint for updates on that specific document. The user didn&#8217;t have to restate any of it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Limitations to keep in mind<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Everything from Part 1&#8217;s limitations still applies: the 10,000-item cap per scope, and the pair of 1,000-requests-per-minute ceilings on search and update calls. Memory writes are still debounced too. Combining SharePoint grounding on top adds a few more.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Every user who talks to the SharePoint-grounded agent needs a Microsoft 365 Copilot license, $30 a month per user, or you need the pay-as-you-go model enabled. That requirement comes from the underlying retrieval API, not from Foundry itself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can attach only one SharePoint tool per agent. If you need to search more than one site, point the connection at a shared parent site that contains the subsites you need.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Your SharePoint site and your Foundry agent have to sit in the same Microsoft Entra tenant (still widely called Azure AD). Cross-tenant access isn&#8217;t supported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The tool doesn&#8217;t work once the agent is published to Microsoft Teams, because Teams runs on the project&#8217;s managed identity instead of passing through the user&#8217;s own identity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tool selection isn&#8217;t perfect. The agent usually picks the right source, but it&#8217;ll occasionally try to answer a SharePoint question from memory alone. Expect to iterate on the system prompt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The architecture stays modular on purpose. MemoryStoreService handles memory operations on its own. SharePointMemoryAgent composes memory and SharePoint tools together, and nothing about that composition is special-cased: add Bing search, Fabric data, or a custom API through MCP, and it drops into the same tools array using the same pattern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s the real shift here. Instead of building and maintaining your own indexing pipeline and state management, you&#8217;re wiring together capabilities the platform already manages. Indexing and permission enforcement happen automatically now. So does memory extraction and consolidation. Your job is the agent&#8217;s behavior and the experience the user actually has.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These features are still in preview, so test thoroughly and keep an eye on your costs. I&#8217;ll update the source repository once the .NET SDK ships native memory support.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Source Code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Complete source code is available on GitHub: <a href=\"https:\/\/github.com\/AhmadiRamin\/sharepoint-grounded-memory-agent\">sharepoint-grounded-memory-agent<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Resources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/foundry\/agents\/concepts\/what-is-memory\">Memory in Foundry Agent Service \u2014 Concepts<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/foundry\/agents\/how-to\/tools\/sharepoint\">SharePoint Tool Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/foundry\/agents\/how-to\/memory-usage\">Create and Use Memory \u2014 How-To Guide<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/foundry\/agents\/overview\">Foundry Agent Service Overview<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/codingwithramin.com\/?p=518\">Building Intelligent SharePoint Agents \u2014 Part 1<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Part 1, we built a Foundry agent with long-term memory that could remember user preferences, roles, and context across sessions without any custom embedding pipelines. If you haven&#8217;t read that post, start there. This one builds directly on top of that code. Memory alone is useful. It just doesn&#8217;t go very far on its own. Knowing a user prefers bullet-point summaries or works in finance is helpful context, but it doesn&#8217;t change what the&hellip;<\/p>\n","protected":false},"author":1,"featured_media":605,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55,72,65,5,3],"tags":[49,51,59,74,7],"class_list":["post-600","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-ai-agent","category-azure-ai-foundry","category-microsoft-azure","category-sharepoint-online","tag-ai","tag-ai-foundry","tag-azure-ai-agent","tag-memory","tag-sharepoint"],"_links":{"self":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/600","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=600"}],"version-history":[{"count":15,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/600\/revisions"}],"predecessor-version":[{"id":840,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/600\/revisions\/840"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/media\/605"}],"wp:attachment":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=600"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=600"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=600"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}