{"id":644,"date":"2026-06-29T18:17:32","date_gmt":"2026-06-29T18:17:32","guid":{"rendered":"https:\/\/codingwithramin.com\/?p=644"},"modified":"2026-07-23T08:56:52","modified_gmt":"2026-07-23T08:56:52","slug":"building-a-conversational-work-iq-agent-in-c-the-a2a-sdk-multi-turn-and-streaming","status":"publish","type":"post","link":"https:\/\/codingwithramin.com\/?p=644","title":{"rendered":"Building a Conversational Work IQ Agent in C#: The A2A SDK, Multi-Turn, and Streaming"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>Part 2 of a series on building agents with the Microsoft Work IQ API. <a href=\"https:\/\/codingwithramin.com\/?p=624\">Part 1<\/a> explained the Work IQ model and made a first grounded call with raw HttpClient.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The raw A2A call in <a href=\"https:\/\/codingwithramin.com\/?p=624\">Part 1<\/a> was useful for one reason: it showed exactly what crossed the wire.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I could see the Work IQ token audience, the JSON-RPC method, the A2A version header and the response shape. That removed a lot of guesswork.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It also produced code I would not want to maintain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The application built the protocol envelope by hand, parsed <strong>JsonDocument <\/strong>nodes by hand and forgot the conversation as soon as the process moved to the next question. The user also saw an empty console while Work IQ assembled the entire answer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is enough for a protocol experiment. It is not yet a conversational agent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This part fixes three things:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>the SDK takes ownership of the A2A protocol;<\/li>\n\n\n\n<li>contextId carries the conversation across turns;<\/li>\n\n\n\n<li>streaming gives the user progress and answer text as they arrive.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The conversation-state piece was particularly interesting to me. In the private AI application our team has been building for clients, memory and context have required deliberate design across agents and sessions. Work IQ&#8217;s short-term conversational context is much simpler: capture an identifier and send it back.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Simple does not mean unimportant. It means the protocol is doing its job.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Version note:<\/strong> This article uses the A2A and MSAL package versions shown below because they match the sample I tested. The A2A SDK was still a preview package when I wrote this, so check NuGet and the current Work IQ samples before upgrading.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>What the SDK actually improves<\/strong><\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I initially expected the A2A SDK to save a few lines of JSON.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It does that, but the more useful change is conceptual. The code starts talking in terms of messages, tasks, artifacts and status updates instead of dictionaries and property names.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That makes the boundary clearer:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>MSAL acquires the delegated token.<\/li>\n\n\n\n<li>HttpClient carries the authentication and A2A version header.<\/li>\n\n\n\n<li>The SDK handles the protocol.<\/li>\n\n\n\n<li>My code handles the conversation and user experience.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">I like that separation. The SDK does not try to own authentication, and the authentication code from <a href=\"https:\/\/codingwithramin.com\/?p=624\">Part 1<\/a> barely changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create the project:<\/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\">PowerShell<\/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>dotnet new console -n Part2.ConversationalAgent\ncd Part2.ConversationalAgent\ndotnet add package A2A --prerelease\ndotnet add package Microsoft.Identity.Client<\/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\">dotnet new console -n Part2.ConversationalAgent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">cd Part2.ConversationalAgent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">dotnet add package A2A --prerelease<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">dotnet add package Microsoft.Identity.Client<\/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 versions I used were:<\/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\">XML<\/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>&lt;Project Sdk=\"Microsoft.NET.Sdk\">\n\n  &lt;PropertyGroup>\n    &lt;OutputType>Exe&lt;\/OutputType>\n    &lt;TargetFramework>net10.0&lt;\/TargetFramework>\n    &lt;ImplicitUsings>enable&lt;\/ImplicitUsings>\n    &lt;Nullable>enable&lt;\/Nullable>\n  &lt;\/PropertyGroup>\n\n  &lt;ItemGroup>\n    &lt;PackageReference Include=\"A2A\" Version=\"1.0.0-preview2\" \/>\n    &lt;PackageReference Include=\"Microsoft.Identity.Client\" Version=\"4.84.2\" \/>\n  &lt;\/ItemGroup>\n\n&lt;\/Project><\/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: #808080\">&lt;<\/span><span style=\"color: #569CD6\">Project<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Sdk<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;Microsoft.NET.Sdk&quot;<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">PropertyGroup<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">OutputType<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">Exe<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">OutputType<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">TargetFramework<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">net10.0<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">TargetFramework<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">ImplicitUsings<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">enable<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">ImplicitUsings<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">Nullable<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">enable<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">Nullable<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">PropertyGroup<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">ItemGroup<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">PackageReference<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Include<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;A2A&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Version<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;1.0.0-preview2&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #808080\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">PackageReference<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Include<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;Microsoft.Identity.Client&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Version<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;4.84.2&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #808080\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">ItemGroup<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">Project<\/span><span style=\"color: #808080\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A small preview-package warning: a custom NuGet configuration can prevent restore from finding A2A. If that happens, add a <strong>nuget.config<\/strong> beside the project and make sure nuget.org is included as a source. The official samples use the same workaround.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>Replace the handwritten envelope<\/strong><\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The first change is deliberately boring. We will ask the same question as <a href=\"https:\/\/codingwithramin.com\/?p=624\">Part 1<\/a>, but the SDK will build and parse the A2A messages.<\/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 System.Net.Http.Headers;\nusing System.Text.Json;\nusing A2A;\nusing Microsoft.Identity.Client;\n\nconst string ClientId = \"&lt;your-app-client-id>\";\nconst string TenantId = \"&lt;your-tenant-id>\";\nconst string Scope    = \"api:\/\/workiq.svc.cloud.microsoft\/.default\";\nconst string Endpoint = \"https:\/\/workiq.svc.cloud.microsoft\/a2a\/\";\n\n\/\/ --- Auth: identical to Part 1 ---\nvar app = PublicClientApplicationBuilder\n    .Create(ClientId)\n    .WithAuthority($\"https:\/\/login.microsoftonline.com\/{TenantId}\")\n    .WithDefaultRedirectUri()\n    .Build();\n\nvar auth = await app.AcquireTokenInteractive(new[] { Scope }).ExecuteAsync();\n\n\/\/ --- Bring your own authed HttpClient, then hand it to the SDK ---\nvar http = new HttpClient();\nhttp.DefaultRequestHeaders.Authorization =\n    new AuthenticationHeaderValue(\"Bearer\", auth.AccessToken);\n\/\/ Still required \u2014 opts in to the A2A v1.0 wire format (see Part 1).\nhttp.DefaultRequestHeaders.TryAddWithoutValidation(\"A2A-Version\", \"1.0\");\n\nvar client = new A2AClient(new Uri(Endpoint), http);\n\n\/\/ --- Build a typed message and send it ---\nvar message = new Message\n{\n    Role      = Role.User,\n    MessageId = Guid.NewGuid().ToString(),\n    Parts     = &#91;Part.FromText(\"What meetings do I have today?\")&#93;,\n    Metadata  = new Dictionary&lt;string, JsonElement>\n    {\n        &#91;\"Location\"&#93; = JsonSerializer.SerializeToElement(new\n        {\n            timeZoneOffset = (int)TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes,\n            timeZone = TimeZoneInfo.Local.Id\n        })\n    }\n};\n\nvar response = await client.SendMessageAsync(new SendMessageRequest { Message = message });\n\n\/\/ The answer text lives in the task's artifacts.\nif (response.PayloadCase == SendMessageResponseCase.Task)\n{\n    var task = response.Task!;\n    var text = string.Join(\"\", task.Artifacts!\n        .SelectMany(a => a.Parts)\n        .Where(p => p.ContentCase == PartContentCase.Text)\n        .Select(p => p.Text));\n    Console.WriteLine(text);\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\">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 style=\"color: #4EC9B0\">Json<\/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\">A2A<\/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\">Identity<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Client<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ClientId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;&lt;your-app-client-id&gt;&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">TenantId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&quot;&lt;your-tenant-id&gt;&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/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;api:\/\/workiq.svc.cloud.microsoft\/.default&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/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 style=\"color: #CE9178\">&quot;https:\/\/workiq.svc.cloud.microsoft\/a2a\/&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ --- Auth: identical to Part 1 ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">app<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">PublicClientApplicationBuilder<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">Create<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">ClientId<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">WithAuthority<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;https:\/\/login.microsoftonline.com\/{<\/span><span style=\"color: #9CDCFE\">TenantId<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">WithDefaultRedirectUri<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">Build<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">auth<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">app<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">AcquireTokenInteractive<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\">[] { <\/span><span style=\"color: #9CDCFE\">Scope<\/span><span style=\"color: #D4D4D4\"> }).<\/span><span style=\"color: #DCDCAA\">ExecuteAsync<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ --- Bring your own authed HttpClient, then hand it to the SDK ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">http<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">HttpClient<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">http<\/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\">    <\/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\">auth<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">AccessToken<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ Still required \u2014 opts in to the A2A v1.0 wire format (see Part 1).<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">http<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">DefaultRequestHeaders<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryAddWithoutValidation<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;A2A-Version&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;1.0&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">client<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">A2AClient<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Uri<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">Endpoint<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #9CDCFE\">http<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ --- Build a typed message and send it ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Message<\/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\">Role<\/span><span style=\"color: #D4D4D4\">      = <\/span><span style=\"color: #9CDCFE\">Role<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">User<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">MessageId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Guid<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">NewGuid<\/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\">    <\/span><span style=\"color: #9CDCFE\">Parts<\/span><span style=\"color: #D4D4D4\">     = &#91;<\/span><span style=\"color: #9CDCFE\">Part<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">FromText<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;What meetings do I have today?&quot;<\/span><span style=\"color: #D4D4D4\">)&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Metadata<\/span><span style=\"color: #D4D4D4\">  = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Dictionary<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">JsonElement<\/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\">        &#91;<\/span><span style=\"color: #CE9178\">&quot;Location&quot;<\/span><span style=\"color: #D4D4D4\">&#93; = <\/span><span style=\"color: #9CDCFE\">JsonSerializer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SerializeToElement<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/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\">timeZoneOffset<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\">)<\/span><span style=\"color: #9CDCFE\">TimeZoneInfo<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Local<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">BaseUtcOffset<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">TotalMinutes<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">timeZone<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">TimeZoneInfo<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Local<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">};<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #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\">client<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SendMessageAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">SendMessageRequest<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> });<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">\/\/ The answer text lives in the task&#39;s artifacts.<\/span><\/span>\n<span class=\"line\"><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\">PayloadCase<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">SendMessageResponseCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Task<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">task<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Task<\/span><span style=\"color: #D4D4D4\">!;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Join<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">task<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Artifacts<\/span><span style=\"color: #D4D4D4\">!<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">SelectMany<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Parts<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">Where<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ContentCase<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">PartContentCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">Select<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The code is shorter, but one response detail still matters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A SendMessageResponse can contain different payload types. In the Work IQ flow above, we expect a Task.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The final answer lives in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Task.Artifacts&#91;].Parts<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The status message is not a second copy of the answer. It carries task state, progress text and metadata such as attributions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I mixed those concepts together the first time I read the response model. Keeping them separate makes both synchronous and streaming handling much easier:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>artifacts are the output;<\/strong><\/li>\n\n\n\n<li><strong>status describes what is happening around that output.<\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>The one value that makes follow-up questions work<\/strong><\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"485\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-2.png\" alt=\"\" class=\"wp-image-770\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-2.png 800w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-2-300x182.png 300w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-2-768x466.png 768w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-2-769x466.png 769w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now we can turn the one-shot call into a conversation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each Work IQ task can carry a <strong>contextId<\/strong>. Put that value on the next user message and Work IQ treats the next request as part of the same conversation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is no need to resend an ever-growing array of previous messages in this sample. The server-side context is represented by the identifier.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a small console REPL:<\/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>string? contextId = null;\nConsole.WriteLine(\"Ask Work IQ something ('quit' to exit).\\n\");\n\nwhile (true)\n{\n    Console.Write(\"You > \");\n    var input = Console.ReadLine();\n    if (string.IsNullOrWhiteSpace(input) ||\n        input.Equals(\"quit\", StringComparison.OrdinalIgnoreCase))\n        break;\n\n    var message = new Message\n    {\n        Role      = Role.User,\n        MessageId = Guid.NewGuid().ToString(),\n        ContextId = contextId,                 \/\/ null on turn 1, reused after\n        Parts     = &#91;Part.FromText(input)&#93;,\n        Metadata  = new Dictionary&lt;string, JsonElement>\n        {\n            &#91;\"Location\"&#93; = JsonSerializer.SerializeToElement(new\n            {\n                timeZoneOffset = (int)TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes,\n                timeZone = TimeZoneInfo.Local.Id\n            })\n        }\n    };\n\n    var response = await client.SendMessageAsync(new SendMessageRequest { Message = message });\n    var task = response.Task!;\n\n    \/\/ Capture the contextId so the *next* turn continues this thread.\n    contextId = task.ContextId ?? contextId;\n\n    var text = string.Join(\"\", task.Artifacts!\n        .SelectMany(a => a.Parts)\n        .Where(p => p.ContentCase == PartContentCase.Text)\n        .Select(p => p.Text));\n    Console.WriteLine(text + \"\\n\");\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #9CDCFE\">contextId<\/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: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Ask Work IQ something (&#39;quit&#39; to exit).<\/span><span style=\"color: #D7BA7D\">\\n<\/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: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;You &gt; &quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ReadLine<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">IsNullOrWhiteSpace<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">) ||<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Equals<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;quit&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">StringComparison<\/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\">        <\/span><span style=\"color: #C586C0\">break<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Message<\/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\">Role<\/span><span style=\"color: #D4D4D4\">      = <\/span><span style=\"color: #9CDCFE\">Role<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">User<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">MessageId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">Guid<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">NewGuid<\/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\">        <\/span><span style=\"color: #9CDCFE\">ContextId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\">,                 <\/span><span style=\"color: #6A9955\">\/\/ null on turn 1, reused after<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Parts<\/span><span style=\"color: #D4D4D4\">     = &#91;<\/span><span style=\"color: #9CDCFE\">Part<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">FromText<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">input<\/span><span style=\"color: #D4D4D4\">)&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Metadata<\/span><span style=\"color: #D4D4D4\">  = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Dictionary<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">JsonElement<\/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\">            &#91;<\/span><span style=\"color: #CE9178\">&quot;Location&quot;<\/span><span style=\"color: #D4D4D4\">&#93; = <\/span><span style=\"color: #9CDCFE\">JsonSerializer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SerializeToElement<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/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\">timeZoneOffset<\/span><span style=\"color: #D4D4D4\"> = (<\/span><span style=\"color: #569CD6\">int<\/span><span style=\"color: #D4D4D4\">)<\/span><span style=\"color: #9CDCFE\">TimeZoneInfo<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Local<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">BaseUtcOffset<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">TotalMinutes<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">timeZone<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">TimeZoneInfo<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Local<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Id<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    };<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/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\">client<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SendMessageAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">SendMessageRequest<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">task<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">response<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Task<\/span><span style=\"color: #D4D4D4\">!;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">    \/\/ Capture the contextId so the *next* turn continues this thread.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">task<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ContextId<\/span><span style=\"color: #D4D4D4\"> ?? <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Join<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">task<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Artifacts<\/span><span style=\"color: #D4D4D4\">!<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">SelectMany<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Parts<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">Where<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ContentCase<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">PartContentCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        .<\/span><span style=\"color: #DCDCAA\">Select<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">&quot;<\/span><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\">Try a follow-up that would be meaningless on its own:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"276\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-5-1024x276.png\" alt=\"\" class=\"wp-image-773\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-5-1024x276.png 1024w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-5-300x81.png 300w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-5-768x207.png 768w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-5-769x208.png 769w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/image-5.png 1104w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The second answer only makes sense because Work IQ remembered the first. No history array, no re-sending the prior turns \u2014 <strong>contextId <\/strong>does it, server-side. If you&#8217;ve read my <a href=\"https:\/\/codingwithramin.com\/?p=592\">Foundry memory posts<\/a>, notice the contrast: there I wired up long-term memory myself; here the conversation state is just part of the protocol.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>Streaming is more than printing tokens<\/strong><\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The synchronous version now works, but the user still waits in silence.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That matters more with Work IQ than with a simple text-completion call. The service may need to find relevant meetings, messages and files before it can assemble the response.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Streaming improves two parts of that experience:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>answer text appears as it becomes available;<\/li>\n\n\n\n<li>status updates show that the request is making progress.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">I deliberately call those messages <strong>status updates<\/strong>, not chain of thought. They are observable progress messages from the service, not the model&#8217;s private reasoning.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Switch from <strong>SendMessageAsync <\/strong>to <strong>SendStreamingMessageAsync<\/strong>. The method returns an <strong>IAsyncEnumerable<\/strong>, so each event can be processed as it arrives.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These are the payloads worth recognising:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table class=\"has-fixed-layout\"><thead><tr><th><code>PayloadCase<\/code><\/th><th>How I use it<\/th><\/tr><\/thead><tbody><tr><td><code>Task<\/code><\/td><td>Capture the initial task and its <code>contextId<\/code><\/td><\/tr><tr><td><code>StatusUpdate<\/code><\/td><td>Render user-facing progress and capture final metadata<\/td><\/tr><tr><td><code>ArtifactUpdate<\/code><\/td><td>Build and display the answer<\/td><\/tr><tr><td><code>Message<\/code><\/td><td>Handle a direct reply if the flow returns one<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"533\" src=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/part2_2.png\" alt=\"\" class=\"wp-image-778\" srcset=\"https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/part2_2.png 800w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/part2_2-300x200.png 300w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/part2_2-768x512.png 768w, https:\/\/codingwithramin.com\/wp-content\/uploads\/2026\/06\/part2_2-769x512.png 769w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The event type is straightforward. The chunking behaviour took more attention.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Append <strong>changes how the chunk should be rendered<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">An ArtifactUpdate contains an Append flag.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When <strong>Append <\/strong>is <strong>true<\/strong>, the new text is a delta. Add it to the buffer and print it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When <strong>Append <\/strong>is <strong>false<\/strong>, the update represents the artifact value at that point. In my tests, Work IQ sent replacement chunks as extensions of the previous text. Printing the complete value every time would duplicate the answer, so the code below prints only the new suffix when possible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is one of those details that looks obvious after you solve it and slightly mysterious before you do.<\/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 System.Text;\n\nstatic async Task&lt;string?> StreamAnswer(A2AClient client, Message message)\n{\n    string? contextId = null;\n    var buffers = new Dictionary&lt;string, StringBuilder>();\n    Dictionary&lt;string, JsonElement>? finalMetadata = null;\n\n    await foreach (var evt in client.SendStreamingMessageAsync(\n        new SendMessageRequest { Message = message }))\n    {\n        switch (evt.PayloadCase)\n        {\n            case StreamResponseCase.Task:\n                contextId = evt.Task!.ContextId;\n                break;\n\n            case StreamResponseCase.StatusUpdate:\n                var status = evt.StatusUpdate!;\n                if (status.Status.Message is { } m)\n                {\n                    contextId     = m.ContextId ?? contextId;\n                    finalMetadata = m.Metadata;          \/\/ where citations currently arrive (terminal event)\n\n                    var thought = JoinText(m.Parts);\n                    if (!string.IsNullOrEmpty(thought))\n                        WriteDim($\"\\n  &#91;{thought}&#93;\");     \/\/ progress \/ status line\n                }\n                break;\n\n            case StreamResponseCase.ArtifactUpdate:\n                var au  = evt.ArtifactUpdate!;\n                var id  = au.Artifact.ArtifactId;\n                if (!buffers.TryGetValue(id, out var sb))\n                    buffers&#91;id&#93; = sb = new StringBuilder();\n\n                var chunk = JoinText(au.Artifact.Parts);\n\n                if (au.Append)\n                {\n                    sb.Append(chunk);\n                    Console.Write(chunk);                 \/\/ print the delta\n                }\n                else\n                {\n                    \/\/ Replace: each chunk is a prefix-extension \u2014 print only the new suffix.\n                    var old = sb.ToString();\n                    sb.Clear();\n                    sb.Append(chunk);\n                    Console.Write(chunk.StartsWith(old, StringComparison.Ordinal)\n                        ? chunk&#91;old.Length..&#93;\n                        : chunk);\n                }\n                break;\n        }\n    }\n\n    if (finalMetadata is not null) PrintCitations(finalMetadata);\n    return contextId;\n\n    static string JoinText(IEnumerable&lt;Part> parts) =>\n        string.Join(\"\", parts\n            .Where(p => p.ContentCase == PartContentCase.Text)\n            .Select(p => p.Text));\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\">System<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Text<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">static<\/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\">StreamAnswer<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">A2AClient<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">client<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">Message<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">? <\/span><span style=\"color: #9CDCFE\">contextId<\/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\">    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">buffers<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Dictionary<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">StringBuilder<\/span><span style=\"color: #D4D4D4\">&gt;();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #4EC9B0\">Dictionary<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">JsonElement<\/span><span style=\"color: #D4D4D4\">&gt;? <\/span><span style=\"color: #9CDCFE\">finalMetadata<\/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\">    <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">foreach<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">evt<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">client<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">SendStreamingMessageAsync<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">SendMessageRequest<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Message<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\"> }))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">switch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">evt<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">PayloadCase<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StreamResponseCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">Task<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">evt<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Task<\/span><span style=\"color: #D4D4D4\">!.<\/span><span style=\"color: #9CDCFE\">ContextId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">break<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StreamResponseCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">StatusUpdate<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">status<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">evt<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">StatusUpdate<\/span><span style=\"color: #D4D4D4\">!;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">status<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Status<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Message<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">is<\/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\">                {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\">     = <\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ContextId<\/span><span style=\"color: #D4D4D4\"> ?? <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">finalMetadata<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Metadata<\/span><span style=\"color: #D4D4D4\">;          <\/span><span style=\"color: #6A9955\">\/\/ where citations currently arrive (terminal event)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">thought<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">JoinText<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">m<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Parts<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">IsNullOrEmpty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">thought<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        <\/span><span style=\"color: #DCDCAA\">WriteDim<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">  &#91;{<\/span><span style=\"color: #9CDCFE\">thought<\/span><span style=\"color: #CE9178\">}&#93;&quot;<\/span><span style=\"color: #D4D4D4\">);     <\/span><span style=\"color: #6A9955\">\/\/ progress \/ status line<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">break<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StreamResponseCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">ArtifactUpdate<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">au<\/span><span style=\"color: #D4D4D4\">  = <\/span><span style=\"color: #9CDCFE\">evt<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ArtifactUpdate<\/span><span style=\"color: #D4D4D4\">!;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">id<\/span><span style=\"color: #D4D4D4\">  = <\/span><span style=\"color: #9CDCFE\">au<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Artifact<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ArtifactId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">buffers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">id<\/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\">sb<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">buffers<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #9CDCFE\">id<\/span><span style=\"color: #D4D4D4\">&#93; = <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">StringBuilder<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">JoinText<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">au<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Artifact<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Parts<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">au<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Append<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\">);                 <\/span><span style=\"color: #6A9955\">\/\/ print the delta<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">else<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\">                    \/\/ Replace: each chunk is a prefix-extension \u2014 print only the new suffix.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">old<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">sb<\/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\">                    <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Clear<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">sb<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Append<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">StartsWith<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">old<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">StringComparison<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Ordinal<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        ? <\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\">&#91;<\/span><span style=\"color: #9CDCFE\">old<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Length<\/span><span style=\"color: #D4D4D4\">..&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                        : <\/span><span style=\"color: #9CDCFE\">chunk<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">break<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">finalMetadata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">PrintCitations<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">finalMetadata<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><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\">JoinText<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">IEnumerable<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #4EC9B0\">Part<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">parts<\/span><span style=\"color: #D4D4D4\">) =&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Join<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">parts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            .<\/span><span style=\"color: #DCDCAA\">Where<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ContentCase<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">PartContentCase<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            .<\/span><span style=\"color: #DCDCAA\">Select<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\"> =&gt; <\/span><span style=\"color: #9CDCFE\">p<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Text<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Use it inside the REPL:<\/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>Console.Write(\"Agent > \");\ncontextId = await StreamAnswer(client, message);\nConsole.WriteLine(\"\\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: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Write<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Agent &gt; &quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contextId<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">StreamAnswer<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">client<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D7BA7D\">\\n<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The user now sees activity while Work IQ gathers context, followed by the answer as it is produced.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The total request may not become dramatically faster. It feels faster because the interface is no longer frozen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That distinction matters in real applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>Citations currently arrive with the final status metadata<\/strong><\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The citation code is similar to <a href=\"https:\/\/codingwithramin.com\/?p=624\">Part 1<\/a>. The difference is where we capture the metadata during the stream.<\/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>static void PrintCitations(Dictionary&lt;string, JsonElement> metadata)\n{\n    if (!metadata.TryGetValue(\"attributions\", out var attrs) ||\n        attrs.ValueKind != JsonValueKind.Array)\n        return;\n\n    Console.WriteLine(\"\\n\\nSources:\");\n    foreach (var a in attrs.EnumerateArray())\n    {\n        var name = a.TryGetProperty(\"providerDisplayName\", out var n) ? n.GetString() : \"(source)\";\n        var url  = a.TryGetProperty(\"seeMoreWebUrl\", out var u) ? u.GetString() : \"\";\n        Console.WriteLine($\"  \u2022 {name}  {url}\");\n    }\n}\n\nstatic void WriteDim(string s)\n{\n    Console.ForegroundColor = ConsoleColor.DarkGray;\n    Console.WriteLine(s);\n    Console.ResetColor();\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">static<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">void<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">PrintCitations<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4EC9B0\">Dictionary<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4EC9B0\">JsonElement<\/span><span style=\"color: #D4D4D4\">&gt; <\/span><span style=\"color: #9CDCFE\">metadata<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">metadata<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;attributions&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\">attrs<\/span><span style=\"color: #D4D4D4\">) ||<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">attrs<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ValueKind<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #9CDCFE\">JsonValueKind<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">Array<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #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\">    <\/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\">a<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">attrs<\/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\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;providerDisplayName&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\">n<\/span><span style=\"color: #D4D4D4\">) ? <\/span><span style=\"color: #9CDCFE\">n<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">GetString<\/span><span style=\"color: #D4D4D4\">() : <\/span><span style=\"color: #CE9178\">&quot;(source)&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">url<\/span><span style=\"color: #D4D4D4\">  = <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">TryGetProperty<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;seeMoreWebUrl&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\">u<\/span><span style=\"color: #D4D4D4\">) ? <\/span><span style=\"color: #9CDCFE\">u<\/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 style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">$&quot;  \u2022 {<\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #CE9178\">}  {<\/span><span style=\"color: #9CDCFE\">url<\/span><span style=\"color: #CE9178\">}&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">static<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">void<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">WriteDim<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">string<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ForegroundColor<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">ConsoleColor<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">DarkGray<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">WriteLine<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">s<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">ResetColor<\/span><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\">At the time I tested this SDK, the attribution array arrived in Status.Message.Metadata.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The upstream Work IQ samples also called out that location as temporary while citation data moves towards a structured data part. That is exactly the sort of preview detail I do not want hidden in a tutorial.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If a later SDK version stops returning <strong>attributions <\/strong>from status metadata, check the artifact parts and current sample code before assuming Work IQ has stopped returning citations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Response shapes move. The requirement to show the sources should not.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>Three things that caught me out<\/strong><\/strong><\/h2>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>The SDK does not remove the need to understand A2A<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">It is still useful to know why the <strong>A2A-Version<\/strong> header exists, where the <strong>contextId <\/strong>comes from and why the answer is an artifact.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Without that mental model, SDK errors become harder to diagnose.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Streaming events are not all answer text<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">My first instinct was to concatenate every text-looking value. That mixes progress messages with the final answer.<br>Treat status and artifacts as separate user-interface channels.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>`contextId` is conversation state, not your entire memory strategy<\/strong><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">It solves follow-up questions in the same conversation. It does not automatically become the durable memory layer for a long-running application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That distinction is important for the client projects we are building. Short-term context and long-term memory have different retention, privacy and product requirements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Chat and Context are different building blocks<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Everything in this article uses the <strong>Chat<\/strong> side of Work IQ. We ask a question and receive a synthesised, cited answer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>Context<\/strong> component serves a different design. It can provide relevant grounding for an agent that wants to perform its own synthesis.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The rough mental model is:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Chat:<\/strong> let Work IQ answer;<\/li>\n\n\n\n<li><strong>Context:<\/strong> let Work IQ gather, then let my agent answer.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">A custom orchestrator may use both. It can ask Work IQ to answer broad work questions and request context when its own model, policies or workflow should control the final output.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I am not expanding that into a second half of this article because it deserves a proper example rather than another feature list.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Is this ready for production?<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It is a much better starting point.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We now have typed protocol objects, multi-turn continuity, streaming progress, streamed artifacts and citations. The calls remain delegated and permission-aware, and I still have no Microsoft 365 retrieval pipeline in the application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Production work remains:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>token caching and refresh;<\/li>\n\n\n\n<li>cancellation and timeout handling;<\/li>\n\n\n\n<li>transient retry rules;<\/li>\n\n\n\n<li>logging without leaking sensitive work content;<\/li>\n\n\n\n<li>a clear user interface for sources and progress;<\/li>\n\n\n\n<li>a deliberate boundary between conversational context and durable memory.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The SDK removed protocol plumbing. It did not remove application engineering.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is the right outcome.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/codingwithramin.com\/?p=654\">Part 3<\/a> changes the model completely. Instead of delegating an entire question to Work IQ, we will expose Microsoft 365 capabilities to our own agent through MCP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is where the experience from our private AI application becomes especially relevant. Once your own orchestrator is making decisions, the challenge is no longer only &#8220;How do I get a grounded answer?&#8221; It becomes &#8220;How do I give this agent useful tools without burying it under hundreds of tool definitions?&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Work IQ&#8217;s answer is ten verbs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Code for this article is in <a href=\"https:\/\/github.com\/AhmadiRamin\/work-iq-samples\">Part2.ConversationalAgent<\/a>. Next: <a href=\"https:\/\/codingwithramin.com\/?p=654\">why the Work IQ MCP server only needs ten tools<\/a>.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part 2 of a series on building agents with the Microsoft Work IQ API. Part 1 explained the Work IQ model and made a first grounded call with raw HttpClient. The raw A2A call in Part 1 was useful for one reason: it showed exactly what crossed the wire. I could see the Work IQ token audience, the JSON-RPC method, the A2A version header and the response shape. That removed a lot of guesswork. It&hellip;<\/p>\n","protected":false},"author":1,"featured_media":653,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55,72,65,5,77],"tags":[49,9,59,78],"class_list":["post-644","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-ai-agent","category-azure-ai-foundry","category-microsoft-azure","category-work-iq","tag-ai","tag-azure","tag-azure-ai-agent","tag-work-iq"],"_links":{"self":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/644","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=644"}],"version-history":[{"count":25,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/644\/revisions"}],"predecessor-version":[{"id":779,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/posts\/644\/revisions\/779"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=\/wp\/v2\/media\/653"}],"wp:attachment":[{"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codingwithramin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}