{"id":33196,"date":"2026-04-20T14:52:09","date_gmt":"2026-04-20T12:52:09","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=33196"},"modified":"2026-04-20T20:29:53","modified_gmt":"2026-04-20T18:29:53","slug":"ag-ui-in-practice-the-sdk-for-typescript","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/","title":{"rendered":"AG-UI in Practice: The SDK for TypeScript"},"content":{"rendered":"<div class=\"wp-post-series-box series-agentic wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-agentic69e9db592ce4a\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-agentic69e9db592ce4a\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 2 of 3 in the series <em>&ldquo;agentic&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/understanding-ag-ui-the-standard-for-agentic-user-interfaces\/\">Understanding AG-UI: The Standard for Agentic User Interfaces<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">AG-UI in Practice: The SDK for TypeScript<\/span><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/implementing-ag-ui-with-angular\/\">Implementing AG-UI with Angular<\/a><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<p><em>Implementing AG-UI with the SDK on the server and in the client<\/em><\/p>\n<p>Once AG-UI defines the semantic messages exchanged between client and agent, the next practical question is immediate: how do you implement these messages concretely on the client and server side? That is exactly what the official SDKs for TypeScript and Python provide, offering ready-made building blocks.<\/p>\n<p>This second part of the series shows how the AG-UI SDK for TypeScript is used on the server and in the browser, how tool calls work with it, and how client tools are described and passed to the agent.<\/p>\n<p>\ud83d\udcc2 <a href=\"https:\/\/github.com\/angular-architects\/flights42\/tree\/agentic\">Source Code<\/a> (see branch <code>agentic<\/code>)<\/p>\n<h2>What Does the AG-UI SDK Provide?<\/h2>\n<p>So that we do not have to start entirely from scratch, AG-UI comes not only with a protocol specification but also with SDKs for TypeScript and Python. Many of the adapters for agent frameworks build on top of them. The Microsoft Agent Framework, by contrast, comes with its own implementation so that AG-UI can also be supported server-side through C#. In addition, the official <a href=\"https:\/\/github.com\/ag-ui-protocol\/ag-ui\/tree\/main\/sdks\/community\">AG-UI repo<\/a> contains community implementations for other languages such as Java and C++, as well as for frameworks like Spring AI.<\/p>\n<p>The official SDKs for TypeScript and Python support HTTP over server-sent events (SSE): each run triggers an HTTP request, after which the server-side agent gradually sends its response to the client as individual text messages and tool calls. These messages can be encoded as JSON or in binary form using Protocol Buffers.<\/p>\n<h2>Using the TypeScript SDK on the Server<\/h2>\n<p>To use the TypeScript SDK, we install the package <code>@ag-ui\/core<\/code> on the server-side. On the client-side we leverage <code>@ag-ui\/client<\/code>.<\/p>\n<p>To illustrate server-side use of the SDK, the following example hardcodes simple AG-UI-compliant messages without using a language model. To do so, the server follows a classic Smalltalk rule \u2014 it\u2019s never wrong to talk about the weather:<\/p>\n<pre><code class=\"language-ts\">import { HttpAgent } from &#039;@ag-ui\/client&#039;;\nimport { BaseEvent, EventType, RunAgentInput } from &#039;@ag-ui\/core&#039;;\nimport { Observable } from &#039;rxjs&#039;;\n\nexport class FlightWeatherAgent extends AbstractAgent {\n  run(input: RunAgentInput): Observable&lt;BaseEvent&gt; {\n    return new Observable((observer) =&gt; {\n      const { threadId, runId } = input;\n      observer.next({ type: EventType.RUN_STARTED, threadId, runId });\n      observer.next({\n        type: EventType.TEXT_MESSAGE_START,\n        messageId: &#039;1001&#039;,\n        role: &#039;assistant&#039;,\n      });\n      observer.next({\n        type: EventType.TEXT_MESSAGE_CONTENT,\n        messageId: &#039;1001&#039;,\n        delta: &#039;Checking flight weather for Frankfurt...&#039;,\n      });\n      observer.next({ type: EventType.TEXT_MESSAGE_END, messageId: &#039;1001&#039; });\n      [...]\n      observer.next({ type: EventType.RUN_FINISHED, threadId, runId });\n      observer.complete();\n    });\n  }\n}<\/code><\/pre>\n<p>The <code>FlightWeatherAgent<\/code> shown here inherits from <code>AbstractAgent<\/code>. Its <code>run<\/code> method processes user requests. It starts a run, sends a text message to the client, and then finishes the run again.<\/p>\n<p>Typically, <code>run<\/code> delegates to an agent framework such as Mastra, LangGraph, Google ADK, Microsoft Agent Framework, or Spring AI and transforms the received information into AG-UI-compliant messages. Usually, you do not have to write such integrations yourself, especially since the AG-UI SDK provides adapters for many frameworks and some frameworks also include their own integration.<\/p>\n<p>It is important to note that the SDK does not handle integration with the chosen transport protocol, for example sending SSE over HTTP. For that reason, the accompanying demo project also contains a small amount of glue code containing a server-side route that registers with the agent and sends all messages as SSE.<\/p>\n<p><div style=\"\nmargin: 8px 0;\npadding: 22px;\nborder: 1px solid #e5e7eb;\nborder-radius: 14px;\nbackground: #f8fafc;\n\">NOTE<\/p>\n<h3 style=\"margin-top:0\">Agentic UI with Angular<\/h3>\n<p>Learn more about this topic in my eBook: Build scalable agentic UIs with Angular \u2014 using AG-UI, A2UI, and MCP Apps, open and free from vendor lock-in.<\/p>\n<p><a href=\"https:\/\/agentic-angular.com\/\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/agentic-book-md.png\" width=\"400\" alt=\"Cover of the eBook Agentic UI with Angular\" style=\"cursor:pointer !important\"><\/a><\/p>\n<p><a style=\"cursor:pointer !important\" href=\"https:\/\/agentic-angular.com\/\">Learn more about the eBook \u2192<\/a>\n<\/div>\n<\/p>\n<h2>Using the TypeScript SDK in the Browser<\/h2>\n<p>On the client side, the TypeScript SDK gives us the option of defining an <code>AgentSubscriber<\/code> with event handlers for incoming messages:<\/p>\n<pre><code class=\"language-ts\">import { AgentSubscriber } from &#039;@ag-ui\/client&#039;;\n\nconst subscriber: AgentSubscriber = {\n  onRunStartedEvent: ({ event }) =&gt; {\n    console.log(\n      `RUN_STARTED: threadId=${event.threadId}, runId=${event.runId}`,\n    );\n  },\n  onTextMessageStartEvent: ({ event }) =&gt; { [...] },\n  onTextMessageContentEvent: ({ event }) =&gt; { [...] },\n  onTextMessageEndEvent: ({ event }) =&gt; { [...] },\n  [...]\n  onRunFinishedEvent: ({ event }) =&gt; { [...] },\n};<\/code><\/pre>\n<p>A dedicated handler exists for each message type. With <code>HttpAgent<\/code>, which is also provided by the SDK, a connection to the server-side agent can be established:<\/p>\n<pre><code class=\"language-ts\">import { FlightWeatherAgent } from &#039;.\/server.js&#039;;\n\nconst threadId = &#039;4711&#039;;\nconst url = &#039;https:\/\/...&#039;;\nconst agent = new HttpAgent({ url, threadId });\n\nconst userMessage = {\n  id: &#039;msg-user-1&#039;,\n  role: &#039;user&#039; as const,\n  content: &#039;What is the flight weather in Frankfurt?&#039;,\n};\n\nagent.addMessage(userMessage);\nawait agent.runAgent({ runId: &#039;0815&#039; }, subscriber);<\/code><\/pre>\n<p>The <code>addMessage<\/code> method initially only appends a message with the user's question to a client-side array. The locally collected messages are not sent until <code>runAgent<\/code> starts the next run. As soon as the responses arrive from the agent via SSE, <code>runAgent<\/code> invokes the corresponding handlers in the <code>AgentSubscriber<\/code> passed in.<\/p>\n<p>Depending on whether the agent remembers the conversation history between runs, the client either sends all previously exchanged messages or only the newly added ones.<\/p>\n<h2>Server-Side Tool Calling with the AG-UI SDK<\/h2>\n<p>So far, our demo has only sent simple text. However, requesting tool calls through the agent works in a very similar way. The information that needs to be sent for this also typically comes from the chosen language model and is transformed by the agent into AG-UI-compliant messages. To keep the demo simple, though, we still make do with a few hardcoded messages:<\/p>\n<pre><code class=\"language-ts\">\/\/ Server Code\n\/\/ Step 1: Tool Call\nobserver.next({\n  type: EventType.TOOL_CALL_START,\n  toolCallId: &#039;2001&#039;,\n  toolCallName: &#039;loadFlightWeather&#039;,\n});\nobserver.next({\n  type: EventType.TOOL_CALL_ARGS,\n  toolCallId: &#039;2001&#039;,\n  delta: &#039;{&quot;city&quot;:&quot;Frankfurt&quot;}&#039;,\n});\nobserver.next({\n  type: EventType.TOOL_CALL_END,\n  toolCallId: &#039;2001&#039;,\n});\n\/\/ Step 2: Execute Server-side Tool\nconst weatherResult = [...];\n\/\/ Step 3: Answer Tool Call\nobserver.next({\n  type: EventType.TOOL_CALL_RESULT,\n  toolCallId: &#039;2001&#039;,\n  messageId: &#039;3001&#039;,\n  role: &#039;tool&#039;,\n  content: JSON.stringify(weatherResult),\n});<\/code><\/pre>\n<p>With the first three messages, the agent indicates that the LLM has requested a tool call. Because it is a server-side tool, the agent executes it itself and returns the result to the language model. In addition, it logs the result by sending another AG-UI message.<\/p>\n<p>Based on these messages, the client can inform the user about the tool call. This creates transparency and prevents the UI from appearing frozen for a longer period of time.<\/p>\n<h2>Client-Side Tool Calling with the AG-UI SDK<\/h2>\n<p>Execution of client-side tools is similar to server-side tools. Here too, the agent communicates the call and its parameters using the tool-call messages we have discussed. The difference is that the client now reacts to these messages by executing a tool and sending the result back in the next run.<\/p>\n<p>However, this initially introduces a challenge: the language model must be informed about the available client-side tools. Here as well, the TypeScript SDK helps us. It provides a <code>Tool<\/code> data type that can be used to define client-side tools. Alongside a name and a textual description, this type also captures information about the expected parameters:<\/p>\n<pre><code class=\"language-ts\">\/\/ Client Code\nimport { Tool } from &#039;@ag-ui\/client&#039;;\nimport { z } from &#039;zod&#039;;\n\nconst weatherSchema = z.object({\n  condition: z.string().describe(&#039;e.g., sunny, cloudy, rainy.&#039;),\n  temperature: z.string().describe(&#039;e.g., 25\u00b0C, 77\u00b0F.&#039;),\n  wind: z.string().describe(&#039;e.g., 5 km\/h, 3 mph.&#039;),\n});\n\nexport const showWeatherTool: Tool = {\n  name: &#039;showWeather&#039;,\n  description: &#039;Provide weather data the client can render.&#039;,\n  parameters: z.toJSONSchema(weatherSchema),\n};<\/code><\/pre>\n<p>The parameters must be defined as JSON Schema. Our example uses the popular schema library <a href=\"https:\/\/zod.dev\/\">zod<\/a> to provide this schema. Based on the description of the tool and its parameters, the LLM can decide when and how to call the tool.<\/p>\n<p>The <code>runAgent<\/code> method accepts the tool descriptions and sends them to the agent:<\/p>\n<pre><code class=\"language-ts\">\/\/ Client Code\n\n\/\/ 1st run\nawait agent.runAgent({ runId: &#039;0815&#039;, tools: [showWeatherTool] }, subscriber);\n\n\/\/ Look into received client-side tool calls and perform respective actions\nconst toolCallResultMessage = [...];\n\n\/\/ Add Tool Call Result\nagent.addMessage(toolCallResultMessage);\n\n\/\/ 2nd run\nawait agent.runAgent({ runId: &#039;0816&#039;, tools: [showWeatherTool] }, subscriber);<\/code><\/pre>\n<p>After each run, the client checks whether the <code>AgentSubscriber<\/code> has received requests for client-side tool calls. If so, it executes those tools and sends the results back to the agent as part of another run.<\/p>\n<h2>AG-UI, Message History, and Client Tools<\/h2>\n<p>Sending the messages stored via <code>addMessage<\/code>, as well as the information about the client tools, happens through the payload of the HTTP request that starts the next run. Unlike the messages discussed so far, the AG-UI protocol does not define the structure of this payload. It is merely an implementation detail of the AG-UI SDK. Because this SDK is official, one can hope that other implementations will align with it.<\/p>\n<h2>Reading Client Tool Information on the Server<\/h2>\n<p>As mentioned earlier, the adapters of the individual agent frameworks pass the received client-tool information on to the LLM. However, if you want to work with this information manually inside the agent, you will find it in the <code>tools<\/code> property of the parameter object passed to <code>run<\/code>:<\/p>\n<pre><code class=\"language-ts\">class FlightWeatherAgent extends AbstractAgent {\n  run(input: RunAgentInput): Observable&lt;BaseEvent&gt; {\n    return new Observable((observer) =&gt; {\n      console.log(&#039;tools&#039;, input.tools);\n      [...]\n    });\n  }\n}<\/code><\/pre>\n<p>This is a JSON Schema containing the parameter descriptions and the textual information that the client defined using <code>Zod<\/code>:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/tool-call-info.png\" alt=\"JSON Schema with parameters and descriptions for a client-side AG-UI tool\" \/><\/p>\n<h2>Summary<\/h2>\n<p>The TypeScript SDK takes a large portion of the AG-UI integration work off your hands. It handles the correct representation and processing of messages and also provides event handlers so the client can react to incoming messages.<\/p>\n<p>The SDK is intentionally low-level. For comfortable use in a framework such as Angular, it therefore needs an additional abstraction. As the second part of the series, this article provides the technical foundation for that. In the next part, we will show how AG-UI can be integrated idiomatically into Angular applications.<\/p>\n<h2>FAQ<\/h2>\n<h3>What Does the AG-UI SDK for TypeScript Do?<\/h3>\n<p>The SDK provides building blocks for creating, sending, and processing AG-UI messages on the server and in the browser. These include agent classes, subscribers for incoming events, and data types for client tools.<\/p>\n<h3>Does the AG-UI SDK Support Server-Sent Events?<\/h3>\n<p>The SDK works well with server-sent events, but it does not handle the transport integration itself. Sending SSE over HTTP still has to be implemented by the application through glue code or a framework.<\/p>\n<h3>What Is the Difference Between Server-Side and Client-Side Tool Calls?<\/h3>\n<p>Server-side tools are executed by the agent itself, and their results are returned to the model. Client-side tools, by contrast, are requested by the agent, executed in the browser, and their results are sent back to the agent in the next run.<\/p>\n<h3>Why Is the TypeScript SDK Still Low-Level?<\/h3>\n<p>The SDK models AG-UI communication cleanly, but it intentionally leaves many convenience features open. In frameworks such as Angular, an additional abstraction is therefore often useful to reduce boilerplate and make the integration more idiomatic.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is post 2 of 3 in the series &ldquo;agentic&rdquo; Understanding AG-UI: The Standard for Agentic User Interfaces AG-UI in Practice: The SDK for TypeScript Implementing AG-UI with Angular Implementing AG-UI with the SDK on the server and in the client Once AG-UI defines the semantic messages exchanged between client and agent, the next practical [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":33193,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-33196","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","post_series-agentic"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>AG-UI in Practice: The SDK for TypeScript - ANGULARarchitects<\/title>\n<meta name=\"description\" content=\"How does the AG-UI SDK for TypeScript work? This article shows how to use it on the server and in the browser, and explains server-sent events, tool calls, and client tools in practice.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AG-UI in Practice: The SDK for TypeScript - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"How does the AG-UI SDK for TypeScript work? This article shows how to use it on the server and in the browser, and explains server-sent events, tool calls, and client tools in practice.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-20T12:52:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-20T18:29:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/Kopie-von-Kopie-von-Kopie-von-Kopie-von-Kopie-von-Blue-White-and-Red-Modern-Digital-Marketing-Agency-Facebook-Ad-1200-x-628-px-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Manfred Steyer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/Kopie-von-Kopie-von-Kopie-von-Kopie-von-Kopie-von-Blue-White-and-Red-Modern-Digital-Marketing-Agency-Facebook-Ad-1200-x-628-px-1.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\"},\"author\":{\"name\":\"Manfred Steyer\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\"},\"headline\":\"AG-UI in Practice: The SDK for TypeScript\",\"datePublished\":\"2026-04-20T12:52:09+00:00\",\"dateModified\":\"2026-04-20T18:29:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\"},\"wordCount\":1362,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\",\"name\":\"AG-UI in Practice: The SDK for TypeScript - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg\",\"datePublished\":\"2026-04-20T12:52:09+00:00\",\"dateModified\":\"2026-04-20T18:29:53+00:00\",\"description\":\"How does the AG-UI SDK for TypeScript work? This article shows how to use it on the server and in the browser, and explains server-sent events, tool calls, and client tools in practice.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg\",\"width\":1000,\"height\":563},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AG-UI in Practice: The SDK for TypeScript\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\",\"name\":\"Manfred Steyer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"AG-UI in Practice: The SDK for TypeScript - ANGULARarchitects","description":"How does the AG-UI SDK for TypeScript work? This article shows how to use it on the server and in the browser, and explains server-sent events, tool calls, and client tools in practice.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/","og_locale":"en_US","og_type":"article","og_title":"AG-UI in Practice: The SDK for TypeScript - ANGULARarchitects","og_description":"How does the AG-UI SDK for TypeScript work? This article shows how to use it on the server and in the browser, and explains server-sent events, tool calls, and client tools in practice.","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/","og_site_name":"ANGULARarchitects","article_published_time":"2026-04-20T12:52:09+00:00","article_modified_time":"2026-04-20T18:29:53+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/Kopie-von-Kopie-von-Kopie-von-Kopie-von-Kopie-von-Blue-White-and-Red-Modern-Digital-Marketing-Agency-Facebook-Ad-1200-x-628-px-1.png","type":"image\/png"}],"author":"Manfred Steyer","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/Kopie-von-Kopie-von-Kopie-von-Kopie-von-Kopie-von-Blue-White-and-Red-Modern-Digital-Marketing-Agency-Facebook-Ad-1200-x-628-px-1.png","twitter_misc":{"Written by":"Manfred Steyer","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/"},"author":{"name":"Manfred Steyer","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a"},"headline":"AG-UI in Practice: The SDK for TypeScript","datePublished":"2026-04-20T12:52:09+00:00","dateModified":"2026-04-20T18:29:53+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/"},"wordCount":1362,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/","name":"AG-UI in Practice: The SDK for TypeScript - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg","datePublished":"2026-04-20T12:52:09+00:00","dateModified":"2026-04-20T18:29:53+00:00","description":"How does the AG-UI SDK for TypeScript work? This article shows how to use it on the server and in the browser, and explains server-sent events, tool calls, and client tools in practice.","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/04\/shutterstock_2650298597.jpg","width":1000,"height":563},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/ag-ui-in-practice-the-sdk-for-typescript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"AG-UI in Practice: The SDK for TypeScript"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a","name":"Manfred Steyer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","caption":"Manfred Steyer"}}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=33196"}],"version-history":[{"count":2,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33196\/revisions"}],"predecessor-version":[{"id":33231,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33196\/revisions\/33231"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/33193"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=33196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=33196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=33196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}