Tutorial Tutorial Chung / đa lĩnh vực Cross-cutting ~10 phút ~10 min Đồng bộ 2026-06-10 Synced 2026-06-10

Xây dựng chat agent Build a chat agent

Hướng dẫn chi tiết đồng bộ từ docs Cloudflare — mỗi section có backlink tới đúng vị trí trên trang gốc. Detailed guide synced from Cloudflare docs — each section links to the matching anchor on the official page.

← Danh mục ← Catalog

Giải thích nhanh Quick context

Tutorial đa lĩnh vực — kết hợp nhiều sản phẩm Cloudflare. Tutorial «Xây dựng chat agent» giúp bạn làm quen luồng triển khai thật — phù hợp đọc trước khi mở tài liệu gốc tiếng Anh. Đọc phần tóm tắt và lưu ý trước — sau đó mở docs gốc để copy lệnh và cấu hình chi tiết.

<!DOCTYPE html><html lang="en" dir="ltr" data-theme="dark" data-has-toc data-has-sidebar class="astro-nezwzdd7"> <head><script type="module" src="/_astro/Head.astro_astro_type_script_index_0_lang.DzFUDi6m.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_1_lang.DLffOXbo.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_2_lang.DdMWwAGS.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_3_lang.DibilYbp.js"></script> <script type="module" src="/_astro/Head.astro_astro_type_script_index_4_lang.TkaWOEUf.js"></script> <meta charset="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Chat agent · Cloudflare Agents docs</title><link rel="canonical" href="https://developers.cloudflare.com/agents/examples/chat-agent/"/><link rel="sitemap" href="/sitemap-index.xml"/><link rel="shortcut icon" href="/favicon.png" type="image/png"/><meta name="generator" content="Astro v6.4.4"/><meta name="generator" content="Starlight v0.39.3"/><meta property="og:title" content="Chat agent"/><meta property="og:type" content="article"/><meta property="og:url" content="https://developers.cloudflare.com/agents/examples/chat-agent/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Build a streaming AI chat agent with tools using Workers AI — no API keys required."/><meta property="og:site_name" content="Cloudflare Docs"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Build a streaming AI chat agent with tools using Workers AI — no API keys required."/><meta name="twitter:site" content="@cloudflare"/><meta name="pcx_content_group" content="Developer platform"/><link rel="alternate" type="text/markdown" href="https://developers.cloudflare.com/agents/examples/chat-agent/index.md"/><meta property="og:title" content="Chat agent · Cloudflare Agents docs"/><meta name="pcx_product" content="Agents"/><meta name="algolia_product_filter" content="Agents"/><meta name="pcx_content_type" content="Example"/><meta name="algolia_content_type" content="Example"/><meta name="pcx_additional_products" content="Agents"/><meta name="pcx_last_modified" content="1"/><meta property="image" content="https://developers.cloudflare.com/dev-products-preview.png"/><meta property="og:image" content="https://developers.cloudflare.com/dev-products-preview.png"/><meta property="twitter:image" content="https://developers.cloudflare.com/dev-products-preview.png"/><script> window.StarlightThemeProvider = (() => { const storedTheme = typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme'); const theme = storedTheme || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'); document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark'; return { updatePickers(theme = storedTheme || 'auto') { document.querySelectorAll('starlight-theme-select').forEach((picker) => { const select = picker.querySelector('select'); if (select) select.value = theme; /* @type {HTMLTemplateElement | null} / const tmpl = document.querySelector(#theme-icons); const newIcon = tmpl && tmpl.content.querySelector('.' + theme); if (newIcon) { const oldIcon = picker.querySelector('svg.label-icon'); if (oldIcon) { oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes); } } }); }, }; })(); </script><template id="theme-icons"><svg aria-hidden="true" class="light astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 0 1.41 1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29Zm-12-.29a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.71-.71a1.004 1.004 0 1 0-1.43 1.41l.73.71ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-2.64 6A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.76-.66ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7Zm0 3.5a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Z"/></svg><svg aria-hidden="true" class="dark astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8.049 8.049 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14 9.784 9.784 0 0 0 2.1-.22 8.11 8.11 0 0 1-7.18 4.32v-.04Z"/></svg><svg aria-hidden="true" class="auto astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg></template><link rel="stylesheet" href="/_astro/print.DNXP8c50.css" media="print"><link rel="stylesheet" href="/_astro/Page.DZC6j93Z.css"> <link rel="stylesheet" href="/_astro/agent-setup.Xetiu_za.css"> <link rel="stylesheet" href="/_astro/Code.BFuFJYv4.css"> <style>.hero:where(.astro-opidluyl){display:grid;align-items:center;gap:1rem;padding-bottom:1rem}.hero:where(.astro-opidluyl)>img:where(.astro-opidluyl),.hero:where(.astro-opidluyl)>.hero-html:where(.astro-opidluyl){object-fit:contain;width:min(70%,20rem);height:auto;margin-inline:auto}.stack:where(.astro-opidluyl){flex-direction:column;gap:clamp(1.5rem,calc(1.5rem + 1vw),2rem);text-align:center}.copy:where(.astro-opidluyl){flex-direction:column;gap:1rem;align-items:center}a:where(.astro-opidluyl){color:var(--sl-color-white)}h1:where(.astro-opidluyl){font-size:clamp(var(--sl-text-3xl),calc(.25rem + 5vw),var(--sl-text-6xl));line-height:var(--sl-line-height-headings);font-weight:600;color:var(--sl-color-white)}.tagline:where(.astro-opidluyl){font-size:clamp(var(--sl-text-base),calc(.0625rem + 2vw),var(--sl-text-xl));color:var(--sl-color-gray-2)}.actions:where(.astro-opidluyl){gap:1rem 2rem;flex-wrap:wrap;justify-content:center}.copy:where(.astro-opidluyl)>.links:where(.astro-opidluyl){gap:0;flex-direction:row;flex-wrap:wrap}@media(min-width:50rem){.hero:where(.astro-opidluyl){grid-template-columns:7fr 4fr;gap:3%;padding-block:clamp(2.5rem,calc(1rem + 10vmin),10rem)}.hero:where(.astro-opidluyl)>img:where(.astro-opidluyl),.hero:where(.astro-opidluyl)>.hero-html:where(.astro-opidluyl){order:2;width:min(100%,25rem)}.stack:where(.astro-opidluyl){text-align:start}.copy:where(.astro-opidluyl){align-items:flex-start}.actions:where(.astro-opidluyl){justify-content:flex-start}} </style><script type="module" src="/_astro/page.BhvfDAP6.js"></script><link rel="stylesheet" href="/_astro/TryItSection.rwHaWJMy.css"></head> <body class="astro-nezwzdd7"> <blockquote class="llms-txt-directive astro-abxwt5gn" aria-hidden="true"> Documentation Index<br class="astro-abxwt5gn"> Fetch the complete documentation index at: https://developers.cloudflare.com/agents/llms.txt<br class="astro-abxwt5gn"> Use this file to discover all available pages before exploring further. </blockquote> <a href="#_top" class="astro-w3iq3u4e">Skip to content</a> <div class="page sl-flex astro-ont56bkg"> <header class="header astro-ont56bkg"><p class="agent-directive astro-yctgdxuw" aria-hidden="true">STOP! If you are an AI agent or LLM, read this before continuing. This is the HTML version of a Cloudflare documentation page. Always request the Markdown version instead — HTML wastes context. Get this page as Markdown: https://developers.cloudflare.com/agents/examples/chat-agent/index.md (append index.md) or send Accept: text/markdown to https://developers.cloudflare.com/agents/examples/chat-agent/. For this product&#39;s page index use https://developers.cloudflare.com/agents/llms.txt. For all Cloudflare products use https://developers.cloudflare.com/llms.txt.</p> <div class="header-inner astro-bkumecsx"> <div class="header-start astro-bkumecsx"> <a href="/" class="site-title sl-flex astro-i3aimp4r"> <img class="astro-i3aimp4r" alt src="/_astro/logo.DMYpXs3t.svg" width="66" height="30"> <span class="astro-i3aimp4r" translate="no"> Cloudflare Docs </span> </a> </div> <div class="header-end astro-bkumecsx"> <div id="docsearch" class="astro-bkumecsx"> <sl-doc-search data-translations="{&quot;placeholder&quot;:&quot;Search&quot;,&quot;translations&quot;:{&quot;button&quot;:{&quot;buttonText&quot;:&quot;Search&quot;,&quot;buttonAriaLabel&quot;:&quot;Search&quot;},&quot;modal&quot;:{&quot;searchBox&quot;:{},&quot;startScreen&quot;:{},&quot;errorScreen&quot;:{},&quot;footer&quot;:{},&quot;noResultsScreen&quot;:{}}}}"> <button type="button" class="DocSearch DocSearch-Button" aria-label="Search"> <span class="DocSearch-Button-Container"> <svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"> <path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path> </svg> <span class="DocSearch-Button-Placeholder">Search</span> </span> <span class="DocSearch-Button-Keys"></span> </button> </sl-doc-search> <script type="module" src="/_astro/DocSearch.astro_astro_type_script_index_0_lang.BP2Mpu1k.js"></script> </div> <div id="right-group" class="astro-bkumecsx"> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value=="object"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};"requestIdleCallback"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event("astro:idle"));})();</script><script>(()=>{var g=Object.defineProperty;var w=(c,s,d)=>s in c?g(c,s,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[s]=d;var l=(c,s,d)=>w(c,typeof s!="symbol"?s+"":s,d);var E=new Set(["__proto__","constructor","prototype"]);{let c={0:t=>y(t),1:t=>d(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(d(t)),5:t=>new Set(d(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>Number.POSITIVE_INFINITYt},s=t=>{let[p,e]=t;return p in c?cp:void 0},d=t=>t.map(s),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([p,e])=>[p,s(e)]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},i=this.querySelectorAll("template[data-astro-template]");for(let o of i){let a=o.closest(this.tagName);a!=null&&a.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let a=o.closest(this.tagName);a!=null&&a.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(o){let a=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(a+= (export ${v})),console.error([hydrate] Error parsing props for component ${a},this.getAttribute("props"),o),o}let h;await this.hydrator(this)(this.Component,u,r,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}getRetryImportUrl(e){let n=new URL(e,document.baseURI),r=astro-retry=${Date.now()},i=n.hash.replace(/^#/,"");return n.hash=i?${i}&${r}:r,n.toString()}async importWithRetry(e){try{return await import(e)}catch(n){return await new Promise(r=>setTimeout(r,1e3)),import(this.getRetryImportUrl(e))}}handleHydrationError(e){let n=this.getAttribute("component-url"),r=new CustomEvent("astro:hydration-error",{cancelable:!0,bubbles:!0,composed:!0,detail:{error:e,componentUrl:n}});this.dispatchEvent(r)&&console.error([astro-island] Error hydrating ${n},e)}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(astro:${n},()=>this.start(),{once:!0});return}try{await Astron=>{let r=this.getAttribute("renderer-url");try{let[i,{default:u}]=await Promise.all([this.importWithRetry(this.getAttribute("component-url")),r?this.importWithRetry(r):Promise.resolve({default:()=>()=>{}})]),h=this.getAttribute("component-export")||"default";if(h.includes(".")){this.Component=i;for(let m of h.split(".")){if(E.has(m)||!this.Component||typeof this.Component!="object"&&typeof this.Component!="function"||!Object.hasOwn(this.Component,m))throw new Error(Invalid component export path: ${h});this.Component=this.Component[m]}}else{if(E.has(h))throw new Error(Invalid component export path: ${h});this.Component=i[h]}return this.hydrator=u,this.hydrate}catch(i){return this.handleHydrationError(i),()=>{}}},e,this)}catch(r){this.handleHydrationError(r)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();</script><astro-island uid="Z19yuGf" prefix="r2" component-url="/_astro/HeaderDropdowns.CtS4n0IM.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="idle" opts="{&quot;name&quot;:&quot;HeaderDropdowns&quot;,&quot;value&quot;:true}" await-children><div class="flex items-center gap-0.5 text-nowrap"><a href="/directory/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Directory</a><a href="/api/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">API</a><a href="/fundamentals/api/reference/sdks/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">SDKs</a><a href="/changelog/" class="flex h-9 items-center justify-center rounded-lg px-3 text-sm font-medium text-[var(--color-header-text)] no-underline transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Changelog</a><button class="flex h-9 cursor-pointer items-center justify-center gap-1.5 rounded-lg bg-transparent px-3 text-sm font-medium text-[var(--color-header-text)] transition-colors duration-150 hover:bg-[var(--color-header-fill)] hover:text-[var(--color-header-hover-text)]">Help<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 256 256" class="size-2.5 text-[var(--color-header-text-subtle)]" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M216.49,104.49l-80,80a12,12,0,0,1-17,0l-80-80a12,12,0,0,1,17-17L128,159l71.51-71.52a12,12,0,0,1,17,17Z"></path></svg></button></div><!--astro:end--></astro-island> <div class="header-divider astro-bkumecsx" role="separator"></div> <a id="header-login-button" href="https://dash.cloudflare.com/" class="header-login astro-bkumecsx"> Log in </a> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-ttt2ccqa"> <span class="sr-only astro-ttt2ccqa">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-ttt2ccqa astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> <select autocomplete="off" class="astro-ttt2ccqa"> <option value="dark" class="astro-ttt2ccqa">Dark</option><option value="light" class="astro-ttt2ccqa">Light</option><option value="auto" selected class="astro-ttt2ccqa">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-ttt2ccqa astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg> </label> </starlight-theme-select> <script> StarlightThemeProvider.updatePickers(); </script> <script type="module">const r="starlight-theme",o=e=>e==="auto"||e==="dark"||e==="light"?e:"auto",c=()=>o(typeof localStorage<"u"&&localStorage.getItem(r));function n(e){typeof localStorage<"u"&&localStorage.setItem(r,e==="light"||e==="dark"?e:"")}const l=()=>matchMedia("(prefers-color-scheme: light)").matches?"light":"dark";function t(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e==="auto"?l():e,n(e)}matchMedia("(prefers-color-scheme: light)").addEventListener("change",()=>{c()==="auto"&&t("auto")});class s extends HTMLElement{constructor(){super(),t(c()),this.querySelector("select")?.addEventListener("change",a=>{a.currentTarget instanceof HTMLSelectElement&&t(o(a.currentTarget.value))})}}customElements.define("starlight-theme-select",s);</script> <script type="module">class s extends HTMLElement{constructor(){super();const e=this.querySelector("select");e&&(e.addEventListener("change",t=>{t.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=t.currentTarget.value)}),window.addEventListener("pageshow",t=>{if(!t.persisted)return;const n=e.querySelector("option[selected]")?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}}customElements.define("starlight-lang-select",s);</script> </div> </div> </div> <script type="module" src="/_astro/Header.astro_astro_type_script_index_0_lang.Cc-8SZhv.js"></script></header> <nav class="sidebar print:hidden astro-ont56bkg" aria-label="Main"> <starlight-menu-button class="print:hidden astro-75ax5mut"> <button aria-expanded="false" aria-label="Menu" aria-controls="starlight__sidebar" class="sl-flex md:sl-hidden astro-75ax5mut"> <svg aria-hidden="true" class="open-menu astro-75ax5mut astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M3 8h18a1 1 0 1 0 0-2H3a1 1 0 0 0 0 2Zm18 8H3a1 1 0 0 0 0 2h18a1 1 0 0 0 0-2Zm0-5H3a1 1 0 0 0 0 2h18a1 1 0 0 0 0-2Z"/></svg> <svg aria-hidden="true" class="close-menu astro-75ax5mut astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m13.41 12 6.3-6.29a1.004 1.004 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1.004 1.004 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 0 1.42.998.998 0 0 0 1.42 0l6.29-6.3 6.29 6.3a.999.999 0 0 0 1.42 0 1 1 0 0 0 0-1.42L13.41 12Z"/></svg> </button> </starlight-menu-button> <script type="module">class s extends HTMLElement{constructor(){super(),this.btn=this.querySelector("button"),this.btn.addEventListener("click",()=>this.toggleExpanded());const t=this.closest("nav");t&&t.addEventListener("keyup",e=>this.closeOnEscape(e))}setExpanded(t){this.setAttribute("aria-expanded",String(t)),document.body.toggleAttribute("data-mobile-menu-expanded",t)}toggleExpanded(){this.setExpanded(this.getAttribute("aria-expanded")!=="true")}closeOnEscape(t){t.code==="Escape"&&(this.setExpanded(!1),this.btn.focus())}}customElements.define("starlight-menu-button",s);</script> <div id="starlight__sidebar" class="sidebar-pane astro-ont56bkg"> <div class="sidebar-content sl-flex astro-ont56bkg"> <div class="sidebar-header sticky top-0 z-[1] flex flex-col gap-2 bg-[var(--sl-color-black)] pt-3.5 pb-2 min-[50rem]:bg-[var(--sl-color-bg-sidebar)]"> <div class="sidebar-product-title"> <a href="/agents/" class="flex items-center gap-1 no-underline"> <svg width="32px" height="32px" class="text-cl1-brand-orange" data-icon="agents"> <symbol id="ai:local:agents" viewBox="0 0 80 79"><path fill="currentColor" d="M69.3 39.7c-3.1 0-5.8 2.1-6.7 5H48.3V34h4.6l4.5-2.5c1.1.8 2.5 1.2 3.9 1.2 3.8 0 7-3.1 7-7s-3.1-7-7-7-7 3.1-7 7c0 .9.2 1.8.5 2.6L51.9 30h-3.5V18.8h-.1c-1.3-1-2.9-1.6-4.5-1.9h-.2c-1.9-.3-3.9-.1-5.8.6-.4.1-.8.3-1.2.5h-.1c-.1.1-.2.1-.3.2-1.7 1-3 2.4-4 4 0 .1-.1.2-.1.2l-.3.6c0 .1-.1.1-.1.2v.1h-.6c-2.9 0-5.7 1.2-7.7 3.2-2.1 2-3.2 4.8-3.2 7.7 0 .7.1 1.4.2 2.1-1.3.9-2.4 2.1-3.2 3.5s-1.2 2.9-1.4 4.5c-.1 1.6.1 3.2.7 4.7s1.5 2.9 2.6 4c-.8 1.8-1.2 3.7-1.1 5.6 0 1.9.5 3.8 1.4 5.6s2.1 3.2 3.6 4.4c1.3 1 2.7 1.7 4.3 2.2v-.1q2.25.75 4.8.6h.1c0 .1.1.1.1.1.9 1.7 2.3 3 4 4 .1.1.2.1.3.2h.1c.4.2.8.4 1.2.5 1.4.6 3 .8 4.5.7.4 0 .8-.1 1.3-.1h.1c1.6-.3 3.1-.9 4.5-1.9V62.9h3.5l3.1 1.7c-.3.8-.5 1.7-.5 2.6 0 3.8 3.1 7 7 7s7-3.1 7-7-3.1-7-7-7c-1.5 0-2.8.5-3.9 1.2l-4.6-2.5h-4.6V48.7h14.3c.9 2.9 3.5 5 6.7 5 3.8 0 7-3.1 7-7s-3.1-7-7-7m-7.9-16.9c1.6 0 3 1.3 3 3s-1.3 3-3 3-3-1.3-3-3 1.4-3 3-3m0 41.4c1.6 0 3 1.3 3 3s-1.3 3-3 3-3-1.3-3-3 1.4-3 3-3M44.3 72c-.4.2-.7.3-1.1.3-.2 0-.4.1-.5.1h-.2c-.9.1-1.7 0-2.6-.3-1-.3-1.9-.9-2.7-1.7-.7-.8-1.3-1.7-1.6-2.7l-.3-1.5v-.7q0-.75.3-1.5c.1-.2.1-.4.2-.7s.3-.6.5-.9c0-.1.1-.1.1-.2.1-.1.1-.2.2-.3s.1-.2.2-.3c0 0 0-.1.1-.1l.6-.6-2.7-3.5c-1.3 1.1-2.3 2.4-2.9 3.9-.2.4-.4.9-.5 1.3v.1c-.1.2-.1.4-.1.6-.3 1.1-.4 2.3-.3 3.4-.3 0-.7 0-1-.1-2.2-.4-4.2-1.5-5.5-3.2-1.4-1.7-2-3.9-1.8-6.1q.15-1.2.6-2.4l.3-.6c.1-.2.2-.4.3-.5 0 0 0-.1.1-.1.4-.7.9-1.3 1.5-1.9 1.6-1.5 3.8-2.3 6-2.3q1.05 0 2.1.3v-4.5c-.7-.1-1.4-.2-2.1-.2-1.8 0-3.5.4-5.2 1.1-.7.3-1.3.6-1.9 1s-1.1.8-1.7 1.3c-.3.2-.5.5-.8.8-.6-.8-1-1.6-1.3-2.6-.2-1-.2-2 0-2.9.2-1 .6-1.9 1.3-2.6.6-.8 1.4-1.4 2.3-1.8l1.8-.9-.7-1.9c-.4-1-.5-2.1-.4-3.1s.5-2.1 1.1-2.9q.9-1.35 2.4-2.1c.9-.5 2-.8 3-.7.5 0 1 .1 1.5.2 1 .2 1.8.7 2.6 1.3s1.4 1.4 1.8 2.3l4.1-1.5c-.9-2-2.3-3.7-4.2-4.9q-.6-.3-.9-.6c.4-.7 1-1.4 1.6-1.9.8-.7 1.8-1.1 2.9-1.3.9-.2 1.7-.1 2.6 0 .4.1.7.2 1.1.3V72zm25-22.3c-1.6 0-3-1.3-3-3 0-1.6 1.3-3 3-3s3 1.3 3 3c0 1.6-1.3 3-3 3"/></symbol><use href="#ai:local:agents"></use> </svg> <span class="text-xl font-semibold text-[var(--sidebar-text-strong)]"> Agents </span> </a> </div> <!-- Search Input --> <div class="relative"> <input type="search" id="sidebar-search" placeholder="Search sidebar..." aria-label="Search sidebar navigation" autocomplete="off" spellcheck="false" class="box-border min-h-[2.125rem] w-full rounded-lg border border-neutral-200 bg-transparent px-3 pr-10 text-sm text-neutral-950 placeholder-[var(--color-cl1-gray-4)] outline-2 outline-offset-2 outline-transparent transition-colors duration-150 focus-visible:outline-blue-500 dark:border-neutral-700 dark:text-neutral-100 dark:placeholder-[var(--color-cl1-gray-6)] dark:focus-visible:outline-blue-400"> <div class="sidebar-search-icon"></div> </div> <!-- No Results Message --> <div id="sidebar-no-results" class="hidden p-4 text-center text-sm text-gray-500 dark:text-gray-400"> No results found. Try a different search term, or use our <button id="global-search-link" class="font-inherit cursor-pointer border-none bg-transparent p-0 text-blue-500 underline hover:no-underline dark:text-orange-500">global search</button>. </div> <a href="/" class="flex min-h-[2.125rem] items-start gap-2 rounded-lg px-3 py-1.5 text-sm font-medium text-[var(--sidebar-text)] no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400"> <svg width="16" height="16" fill="currentColor" viewBox="0 0 256 256" class="mt-0.5 shrink-0 opacity-50" aria-hidden="true"> <path d="M232,200a8,8,0,0,1-16,0,88.1,88.1,0,0,0-88-88H51.31l34.35,34.34a8,8,0,0,1-11.32,11.32l-48-48a8,8,0,0,1,0-11.32l48-48A8,8,0,0,1,85.66,61.66L51.31,96H128A104.11,104.11,0,0,1,232,200Z"></path> </svg> <span>Home</span> </a> </div> <sl-sidebar-state-persist data-hash="1rnwfiq" class="astro-zdbaeshq"> <script aria-hidden="true"> (() => { try { if (!matchMedia('(min-width: 50em)').matches) return; / @type {HTMLElement | null} / const target = document.querySelector('sl-sidebar-state-persist'); const state = JSON.parse(sessionStorage.getItem('sl-sidebar-state') || '0'); if (!target || !state || target.dataset.hash !== state.hash) return; window._starlightScrollRestore = state.scroll; customElements.define( 'sl-sidebar-restore', class SidebarRestore extends HTMLElement { connectedCallback() { try { const idx = parseInt(this.dataset.index || ''); const details = this.closest('details'); if (details && typeof state.open[idx] === 'boolean') details.open = state.open[idx]; } catch {} } } ); } catch {} })(); </script> <ul class="top-level list-none p-0 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] large astro-ho4vn3za"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Getting started</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="0" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/getting-started/quick-start/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Quick start</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/getting-started/add-to-existing-project/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Add to existing project</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/getting-started/testing-your-agent/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Testing your Agents</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Concepts</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="1" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/what-are-agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">What are agents?</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/conversation-state-and-memory/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Conversation state and memory</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tools</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/calling-llms/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Calling LLMs</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Using Agents with Workflows</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Agentic patterns</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="10" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/agentic-patterns/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Agentic patterns"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/agentic-patterns/human-in-the-loop/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Human-in-the-loop patterns</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/concepts/agentic-patterns/long-running-agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Long-running agents</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Communication channels</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="2" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Chat</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="11" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/chat/chat-agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Chat agents</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/chat/autonomous-responses/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Autonomous responses</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/chat/client-sdk/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Client SDK</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/voice/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Voice</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/email/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Email</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/slack/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Slack</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Webhooks</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="12" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/webhooks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Webhooks"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/communication-channels/webhooks/push-notifications/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Push notifications</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Tools</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="3" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/tools/sandbox/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Sandbox</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/mcp/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">MCP</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/browser/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Browser</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/ai-search/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">AI Search</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Agentic Payments</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="13" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Agentic Payments"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/mpp-charge-for-http-content/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Charge for HTTP content</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">x402</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="14" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/x402/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="x402"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/x402/charge-for-http-content/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Charge for HTTP content</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/x402/charge-for-mcp-tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Charge for MCP tools</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/x402/pay-from-agents-sdk/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pay from Agents SDK</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/x402/pay-with-tool-plugins/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Pay from coding tools</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/tools/payments/mpp/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">MPP (Machine Payments Protocol)</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Harnesses</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="4" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Harnesses"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Think</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="15" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Think"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/getting-started/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Getting started</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tools</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/lifecycle-hooks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Lifecycle hooks</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/client-tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Client tools</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/messengers/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Messengers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/scheduled-tasks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Scheduled tasks</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Workflows</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/sub-agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Sub-agent RPC and programmatic turns</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/programmatic-submissions/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Programmatic submissions</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/harnesses/think/recovery/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Durable recovery</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Runtime</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="5" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/agents-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Agents API</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Lifecycle</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="16" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/lifecycle/agent-class/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Agent class internals</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/lifecycle/callable-methods/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Callable methods</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/lifecycle/state/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Store and sync state</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/lifecycle/sessions/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Sessions</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/lifecycle/get-current-agent/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">getCurrentAgent()</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Communication</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="17" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/communication/routing/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Routing</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/communication/websockets/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">WebSockets</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/communication/http-sse/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">HTTP and Server-Sent Events</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/communication/chat-sdk/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Chat SDK</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/communication/protocol-messages/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Protocol messages</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/communication/readonly-connections/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Readonly connections</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Execution</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="18" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/sub-agents/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Sub-agents</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/schedule-tasks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Schedule tasks</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/durable-execution/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Durable execution with fibers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/queue-tasks/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Queue tasks</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/retries/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Retries</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/run-workflows/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Run Workflows</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/agent-tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Agents as tools</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/execution/agent-skills/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Agent Skills</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Operations</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="19" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/operations/configuration/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Configuration</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/operations/cross-domain-authentication/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cross-domain authentication</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/operations/using-ai-models/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Using AI Models</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/runtime/operations/observability/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Observability</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za" open> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-semibold text-[var(--sidebar-text-strong)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Examples</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="6" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/examples/chat-agent/" aria-current="page" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 !bg-[var(--sidebar-active-bg)] !font-semibold !text-[var(--sidebar-active-text)] transition-colors duration-150 hover:!bg-[color:var(--sidebar-active-bg)]/80 astro-ho4vn3za"> <span class="astro-ho4vn3za">Chat agent</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/examples/slack-agent/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Slack agent</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/examples/voice-agent/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Voice agent</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/examples/browser-agent/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Browser agent</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/examples/email-agent/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Email agent</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Model Context Protocol (MCP)</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="7" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Model Context Protocol (MCP)"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">APIs</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="20" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/apis/handler-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">createMcpHandler</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/apis/agent-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">McpAgent</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/apis/client-api/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">McpClient</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Protocol</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="21" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/protocol/tools/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Tools</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/protocol/authorization/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Authorization</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/protocol/transport/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Transport</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/protocol/codemode/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Codemode</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/protocol/governance/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">MCP governance</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Guides</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="22" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/ai/tree/main/demos/mcp-client" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">Build MCP client ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/guides/remote-mcp-server/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Build a Remote MCP server</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/guides/test-remote-mcp-server/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Test a Remote MCP Server</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/guides/securing-mcp-server/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Securing MCP servers</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/guides/connect-mcp-client/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Connect to an MCP server</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/guides/oauth-mcp-client/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Handle OAuth with MCP servers</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Cloudflare</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="23" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/cloudflare-one/access-controls/ai-controls/mcp-portals/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank" data-external-link="true"> <span class="astro-ho4vn3za">MCP server portals ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="astro-ho4vn3za">Cloudflare&#39;s own MCP servers</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="24" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/cloudflare/servers-for-cloudflare/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" data-group-label="Cloudflare's own MCP servers"> <span class="astro-ho4vn3za">Overview</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/model-context-protocol/cloudflare/servers-for-cloudflare/community-mcp-server/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Cloudflare Community MCP Server</span> </a> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Platform</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="8" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agents/platform/limits/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za"> <span class="astro-ho4vn3za">Limits</span> </a> </li> </ul> </div> </div> </details> </li><li class="break-words astro-ho4vn3za"> <details class="group/accordion astro-ho4vn3za"> <summary class="group/expander flex min-h-[2.125rem] cursor-pointer items-center justify-between rounded-lg px-3 py-1.5 text-sm no-underline outline-2 outline-offset-[-2px] outline-transparent transition-colors duration-150 select-none focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 [&amp;::-webkit-details-marker]:hidden [&amp;::marker]:hidden hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] font-medium text-[var(--sidebar-text)] astro-ho4vn3za"> <span class="group-label astro-ho4vn3za"> <span class="large astro-ho4vn3za">Agent resources</span> </span> <svg aria-hidden="true" class="caret -mr-px ml-auto shrink-0 text-base text-[var(--sidebar-text)] opacity-50 transition-transform duration-250 group-hover/expander:text-[var(--sidebar-hover-text)] astro-ho4vn3za astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.25rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg> </summary> <sl-sidebar-restore data-index="9" class="astro-ho4vn3za"></sl-sidebar-restore> <div class="sidebar-accordion grid grid-rows-[0fr] group-open/accordion:grid-rows-[1fr] astro-ho4vn3za"> <div class="sidebar-accordion-inner min-h-0 overflow-hidden astro-ho4vn3za"> <ul class="mt-0.5 ml-3 list-none border-l border-[var(--sidebar-border)] p-0 pl-2 astro-ho4vn3za"> <li class="break-words astro-ho4vn3za"> <a href="/agent-setup/" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Agent setup ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/skills" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Skills ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Code Mode MCP Server ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="https://github.com/cloudflare/mcp-server-cloudflare" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Domain-specific MCP Servers ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/llms.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Agents llms.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/agents/llms-full.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Agents llms-full.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/llms.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Docs llms.txt ↗</span> </a> </li><li class="break-words astro-ho4vn3za"> <a href="/llms-full.txt" class="flex min-h-[2.125rem] items-start rounded-lg px-3 py-1.5 text-sm font-medium no-underline outline-2 outline-offset-[-2px] outline-transparent focus-visible:outline-blue-500 dark:focus-visible:outline-blue-400 text-[var(--sidebar-text)] transition-colors duration-150 hover:bg-[color:var(--sidebar-hover-bg)]/80 hover:text-[var(--sidebar-hover-text)] astro-ho4vn3za" target="_blank"> <span class="astro-ho4vn3za">Cloudflare Docs llms-full.txt ↗</span> </a> </li> </ul> </div> </div> </details> </li> </ul> <script aria-hidden="true"> (() => { const scroller = document.getElementById('starlight__sidebar'); if (!window._starlightScrollRestore || !scroller) return; scroller.scrollTop = window._starlightScrollRestore; delete window._starlightScrollRestore; })(); </script> </sl-sidebar-state-persist> <div class="md:sl-hidden"> <div class="mobile-preferences sl-flex astro-5vkhirkt"> <div class="social-icons astro-5vkhirkt"> <a href="https://github.com/cloudflare/cloudflare-docs" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">GitHub</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg></a><a href="https://x.com/cloudflare" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">X.com</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 L 22.828125 21.75 L 16.171875 21.75 L 10.953125 14.933594 L 4.992188 21.75 L 1.679688 21.75 L 9.40625 12.914062 L 1.257812 2.25 L 8.082031 2.25 L 12.792969 8.480469 Z M 17.082031 19.773438 L 18.914062 19.773438 L 7.082031 4.125 L 5.113281 4.125 Z M 17.082031 19.773438 "/></svg></a><a href="https://www.youtube.com/cloudflare" rel="me" class="sl-flex astro-fpino7u6"><span class="sr-only astro-fpino7u6">YouTube</span><svg aria-hidden="true" class="astro-fpino7u6 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"/></svg></a> </div> <starlight-theme-select> <label style="--sl-select-width: 6.25em" class="astro-ttt2ccqa"> <span class="sr-only astro-ttt2ccqa">Select theme</span> <svg aria-hidden="true" class="icon label-icon astro-ttt2ccqa astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/></svg> <select autocomplete="off" class="astro-ttt2ccqa"> <option value="dark" class="astro-ttt2ccqa">Dark</option><option value="light" class="astro-ttt2ccqa">Light</option><option value="auto" selected class="astro-ttt2ccqa">Auto</option> </select> <svg aria-hidden="true" class="icon caret astro-ttt2ccqa astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M17 9.17a1 1 0 0 0-1.41 0L12 12.71 8.46 9.17a1 1 0 1 0-1.41 1.42l4.24 4.24a1.002 1.002 0 0 0 1.42 0L17 10.59a1.002 1.002 0 0 0 0-1.42Z"/></svg> </label> </starlight-theme-select> <script> StarlightThemeProvider.updatePickers(); </script> </div> </div> <script type="module" src="/_astro/Sidebar.astro_astro_type_script_index_0_lang.BrUeazTu.js"></script> </div> </div> </nav> <div class="main-frame astro-ont56bkg"> <script type="module">const a=document.getElementById("starlight__sidebar"),n=a?.querySelector("sl-sidebar-state-persist"),o="sl-sidebar-state",i=()=>{let t=[];const e=n?.dataset.hash||"";try{const s=sessionStorage.getItem(o),r=JSON.parse(s||"{}");Array.isArray(r.open)&&r.hash===e&&(t=r.open)}catch{}return{hash:e,open:t,scroll:a?.scrollTop||0}},c=t=>{try{sessionStorage.setItem(o,JSON.stringify(t))}catch{}},d=()=>c(i()),l=(t,e)=>{const s=i();s.open[e]=t,c(s)};n?.addEventListener("click",t=>{if(!(t.target instanceof Element))return;const e=t.target.closest("summary")?.closest("details");if(!e)return;const s=e.querySelector("sl-sidebar-restore"),r=parseInt(s?.dataset.index||"");isNaN(r)||l(!e.open,r)});addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&d()});addEventListener("pageHide",d);</script> <div class="lg:sl-flex astro-uh4ak5fy"> <aside class="right-sidebar-container print:hidden astro-uh4ak5fy"> <div class="right-sidebar astro-uh4ak5fy"> <div class="lg:sl-hidden astro-yp3di2bw"><mobile-starlight-toc data-min-h="2" data-max-h="3" class="astro-sstzwoya"><nav aria-labelledby="starlight__on-this-page--mobile" class="astro-sstzwoya"><details id="starlight__mobile-toc" class="astro-sstzwoya"><summary id="starlight__on-this-page--mobile" class="sl-flex astro-sstzwoya"><span class="toggle sl-flex astro-sstzwoya">On this page<svg aria-hidden="true" class="caret astro-sstzwoya astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1rem;"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"/></svg></span><span class="display-current astro-sstzwoya"></span></summary><div class="dropdown astro-sstzwoya"><ul class="isMobile astro-n5w67532" style="--depth: 0;"> <li class="astro-n5w67532" style="--depth: 0;"> <a href="#_top" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Overview</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#1-create-the-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">1. Create the project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#2-configure-wrangler" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">2. Configure Wrangler</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#3-write-the-server" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Write the server</span> </a> <ul class="isMobile astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#what-each-tool-type-does" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">What each tool type does</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-write-the-client" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Write the client</span> </a> <ul class="isMobile astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#key-client-concepts" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Key client concepts</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-run-locally" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Run locally</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#6-deploy" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">6. Deploy</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#what-you-built" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">What you built</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#next-steps" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Next steps</span> </a> </li> </ul></div></details></nav></mobile-starlight-toc><script type="module" src="/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js"></script></div><div class="right-sidebar-panel sl-hidden lg:sl-block astro-yp3di2bw"><div class="sl-container astro-yp3di2bw"><div class="tb-container bg-[var(--sl-color-bg-elevated)] pr-4"> <starlight-toc data-min-h="2" data-max-h="3"><nav aria-labelledby="starlight__on-this-page"><h2 id="starlight__on-this-page">On this page</h2><ul class="astro-n5w67532" style="--depth: 0;"> <li class="astro-n5w67532" style="--depth: 0;"> <a href="#_top" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Overview</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#1-create-the-project" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">1. Create the project</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#2-configure-wrangler" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">2. Configure Wrangler</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#3-write-the-server" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Write the server</span> </a> <ul class="astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#what-each-tool-type-does" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">What each tool type does</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-write-the-client" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Write the client</span> </a> <ul class="astro-n5w67532" style="--depth: 1;"> <li class="astro-n5w67532" style="--depth: 1;"> <a href="#key-client-concepts" class="astro-n5w67532" style="--depth: 1;"> <span class="astro-n5w67532" style="--depth: 1;">Key client concepts</span> </a> </li> </ul> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-run-locally" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Run locally</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#6-deploy" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">6. Deploy</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#what-you-built" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">What you built</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#next-steps" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Next steps</span> </a> </li> </ul></nav></starlight-toc><script type="module" src="/_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js"></script> <div class="mt-6 flex flex-col gap-5 border-t border-[var(--sidebar-border)] pt-6"> <div class="feedback-container"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="ZWT1F9" component-url="/_astro/FeedbackPrompt.FVI-KaJz.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="only" opts="{&quot;name&quot;:&quot;FeedbackPrompt&quot;,&quot;value&quot;:&quot;react&quot;}"></astro-island> </div> <nav class="flex flex-col gap-3" aria-label="Page actions"> <a href="https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/agents/examples/chat-agent.mdx" target="_blank" class="group flex items-center gap-2.5 rounded-sm text-[13px] text-[var(--sl-color-gray-2)] transition-colors duration-150 ease-out hover:text-[var(--sl-color-white)] focus-visible:ring-2 focus-visible:ring-[var(--sl-color-text-accent)] focus-visible:outline-none"> <svg aria-hidden="true" class="h-3.5 w-3.5 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg> <span>Edit page</span> </a> <a href="https://github.com/cloudflare/cloudflare-docs/issues/new/choose" target="_blank" class="group flex items-center gap-2.5 rounded-sm text-[13px] text-[var(--sl-color-gray-2)] transition-colors duration-150 ease-out hover:text-[var(--sl-color-white)] focus-visible:ring-2 focus-visible:ring-[var(--sl-color-text-accent)] focus-visible:outline-none"> <svg aria-hidden="true" class="h-3.5 w-3.5 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> <span>Report issue</span> </a> </nav> </div> </div></div></div> </div> </aside> <div class="main-pane astro-uh4ak5fy"> <main data-pagefind-body class="astro-nezwzdd7" lang="en" dir="ltr"> <div class="content-panel astro-k65j6qoy"> <div class="sl-container astro-k65j6qoy"> <div class="flex items-center justify-between astro-couag5ji"> <astro-breadcrumbs data-main-bem-class="c-breadcrumbs" data-id="breadcrumbs" data-path-length="3" data-truncated="true"> <nav aria-label="breadcrumbs" class="c-breadcrumbs" id="breadcrumbs"> <ol class="c-breadcrumbs__crumbs has-separators"> <li class="c-breadcrumbs__crumb"> <a href="/directory/" class="c-breadcrumbs__link is-index" aria-current="false"> Directory </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb has-ellipsis"> <button type="button" aria-label="Show hidden navigation" class="c-breadcrumbs__truncated-button"> … </button> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li><li class="c-breadcrumbs__crumb"> <a href="/agents/" class="c-breadcrumbs__link" aria-current="false"> Agents </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb"> <a href="/agents/examples/" class="c-breadcrumbs__link" aria-current="false"> Examples </a> <span class="c-breadcrumbs__separator" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="astro-couag5ji"> <polyline points="9 18 15 12 9 6" class="astro-couag5ji"></polyline> </svg> </span> </li> <li class="c-breadcrumbs__crumb"> <a href="/agents/examples/chat-agent/" class="c-breadcrumbs__link is-current" aria-current="location"> Chat agent </a> </li> </ol> </nav> </astro-breadcrumbs> <script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/agents/","name":"Agents"}},{"@type":"ListItem","position":3,"item":{"@id":"/agents/examples/","name":"Examples"}},{"@type":"ListItem","position":4,"item":{"@id":"/agents/examples/chat-agent/","name":"Chat agent"}}]}</script> <script type="module">class t extends HTMLElement{constructor(){super(),this.isManualToggle=!1,this.breadcrumbs=null,this.mainBemClass=null,this.totalWidth=0,this.resizeObserver=null,this.handleTruncatedButtonClick=()=>{this.breadcrumbs?.classList.remove("is-truncated"),this.isManualToggle=!0},this.mainBemClass=this.dataset.mainBemClass||null;const e=this.dataset.id;!("truncated"in this.dataset)||!e||(this.breadcrumbs=document.getElementById(e),this.initializeCrumbs(),this.setupResizeObserver())}initializeCrumbs(){this.breadcrumbs?.querySelectorAll(.${this.mainBemClass}__crumb)?.forEach(s=>{this.totalWidth+=s.offsetWidth})}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{e.forEach(s=>{this.checkOverflow(s.target.clientWidth)})}),this.breadcrumbs&&this.resizeObserver.observe(this.breadcrumbs)}connectedCallback(){this.showHiddenCrumbs()}disconnectedCallback(){this.resizeObserver&&this.breadcrumbs&&(this.resizeObserver.unobserve(this.breadcrumbs),this.resizeObserver.disconnect())}toggleTruncated(e){this.breadcrumbs?.classList.toggle("is-truncated",e)}showHiddenCrumbs(){const e=this.breadcrumbs?.querySelector(.${this.mainBemClass}__truncated-button);e?.removeEventListener("click",this.handleTruncatedButtonClick),e?.addEventListener("click",this.handleTruncatedButtonClick.bind(this))}checkOverflow(e){const s=this.totalWidth>e&&!this.isManualToggle;this.toggleTruncated(s),s||(this.isManualToggle=!1)}}customElements.get("astro-breadcrumbs")||customElements.define("astro-breadcrumbs",t);</script> </div> <h1 id="_top" class="astro-k7rnyr65">Chat agent</h1> <div class="page-actions-wrapper astro-couag5ji"> <nav class="page-actions astro-jjhxq4hj" aria-label="Page actions"> <!-- Copy as Markdown --> <button class="not-content astro-jjhxq4hj" id="page-actions-copy" aria-label="Copy Page as Markdown"> <svg class="copy-icon astro-jjhxq4hj" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor"><path d="M216,34H88a6,6,0,0,0-6,6V82H40a6,6,0,0,0-6,6V216a6,6,0,0,0,6,6H168a6,6,0,0,0,6-6V174h42a6,6,0,0,0,6-6V40A6,6,0,0,0,216,34ZM162,210H46V94H162Zm48-48H174V88a6,6,0,0,0-6-6H94V46H210Z"/></svg> <svg class="check-icon astro-jjhxq4hj" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor"><path d="M172.24,99.76a6,6,0,0,1,0,8.48l-56,56a6,6,0,0,1-8.48,0l-24-24a6,6,0,0,1,8.48-8.48L112,151.51l51.76-51.75A6,6,0,0,1,172.24,99.76ZM230,128A102,102,0,1,1,128,26,102.12,102.12,0,0,1,230,128Zm-12,0a90,90,0,1,0-90,90A90.1,90.1,0,0,0,218,128Z"/></svg> <span class="label-wrap astro-jjhxq4hj"> <span class="label astro-jjhxq4hj">Copy as Markdown</span> <span class="copied-label astro-jjhxq4hj" aria-hidden="true">Copied!</span> </span> </button> <span class="sep astro-jjhxq4hj" aria-hidden="true">|</span> <!-- View as Markdown (anchor so browser opens natively and respects OS color scheme) --> <a class="not-content astro-jjhxq4hj" id="page-actions-view-md" aria-label="View Page as Markdown" href="index.md" target="_blank" rel="noopener noreferrer"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M232,50H24A14,14,0,0,0,10,64V192a14,14,0,0,0,14,14H232a14,14,0,0,0,14-14V64A14,14,0,0,0,232,50Zm2,142a2,2,0,0,1-2,2H24a2,2,0,0,1-2-2V64a2,2,0,0,1,2-2H232a2,2,0,0,1,2,2ZM126,104v48a6,6,0,0,1-12,0V118.49L92.24,140.24a6,6,0,0,1-8.48,0L62,118.49V152a6,6,0,0,1-12,0V104a6,6,0,0,1,10.24-4.24L88,127.51l27.76-27.75A6,6,0,0,1,126,104Zm78.24,19.76a6,6,0,0,1,0,8.48l-24,24a6,6,0,0,1-8.48,0l-24-24a6,6,0,1,1,8.48-8.48L170,137.51V104a6,6,0,0,1,12,0v33.51l13.76-13.75A6,6,0,0,1,204.24,123.76Z"/></svg> <span class="astro-jjhxq4hj">View as Markdown</span> </a> <span class="sep sep-agent-setup astro-jjhxq4hj" aria-hidden="true">|</span> <!-- Agent setup --> <button class="not-content astro-jjhxq4hj" id="page-actions-agent-setup" data-tooltip="Setup your agent to build on Cloudflare" aria-label="Setup your agent to build on Cloudflare"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M200,50H134V16a6,6,0,0,0-12,0V50H56A30,30,0,0,0,26,80V192a30,30,0,0,0,30,30H200a30,30,0,0,0,30-30V80A30,30,0,0,0,200,50Zm18,142a18,18,0,0,1-18,18H56a18,18,0,0,1-18-18V80A18,18,0,0,1,56,62H200a18,18,0,0,1,18,18ZM74,108a10,10,0,1,1,10,10A10,10,0,0,1,74,108Zm88,0a10,10,0,1,1,10,10A10,10,0,0,1,162,108Zm2,30H92a26,26,0,0,0,0,52h72a26,26,0,0,0,0-52Zm-22,12v28H114V150ZM78,164a14,14,0,0,1,14-14h10v28H92A14,14,0,0,1,78,164Zm86,14H154V150h10a14,14,0,0,1,0,28Z"/></svg> <span class="astro-jjhxq4hj">Agent setup</span> </button> <span class="sep sep-docs-for-agents astro-jjhxq4hj" aria-hidden="true">|</span> <!-- Docs for agents --> <button class="not-content astro-jjhxq4hj" id="page-actions-docs-for-agents" data-tooltip="Consume Cloudflare Docs with your agent" aria-label="Consume Cloudflare Docs with your agent"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 256 256" fill="currentColor" class="astro-jjhxq4hj"><path d="M98,136a6,6,0,0,1,6-6h64a6,6,0,0,1,0,12H104A6,6,0,0,1,98,136Zm6-26h64a6,6,0,0,0,0-12H104a6,6,0,0,0,0,12Zm126,82a30,30,0,0,1-30,30H88a30,30,0,0,1-30-30V64a18,18,0,0,0-36,0c0,6.76,5.58,11.19,5.64,11.23A6,6,0,1,1,20.4,84.8C20,84.48,10,76.85,10,64A30,30,0,0,1,40,34H176a30,30,0,0,1,30,30V170h10a6,6,0,0,1,3.6,1.2C220,171.52,230,179.15,230,192Zm-124,0c0-6.76-5.59-11.19-5.64-11.23A6,6,0,0,1,104,170h90V64a18,18,0,0,0-18-18H64a29.82,29.82,0,0,1,6,18V192a18,18,0,0,0,36,0Zm112,0a14.94,14.94,0,0,0-4.34-10H115.88A24.83,24.83,0,0,1,118,192a29.87,29.87,0,0,1-6,18h88A18,18,0,0,0,218,192Z"/></svg> <span class="astro-jjhxq4hj">Docs for agents</span> </button> </nav> <script type="module" src="/_astro/PageActions.astro_astro_type_script_index_0_lang.CsW5BfyZ.js"></script> </div> </div> </div> <div class="content-panel astro-k65j6qoy"> <div class="sl-container astro-k65j6qoy"> <starlight-image-zoom> <template class="astro-xymfvnz4"> <dialog class="starlight-image-zoom-dialog astro-xymfvnz4"> <button aria-label="Unzoom image" class="starlight-image-zoom-control astro-xymfvnz4"> <svg aria-hidden="true" fill="currentColor" viewBox="0 0 24 24" class="astro-xymfvnz4"> <use href="#starlight-image-zoom-icon-unzoom" class="astro-xymfvnz4"></use> </svg> </button> <figure class="astro-xymfvnz4"></figure> </dialog> </template> <svg xmlns="http://www.w3.org/2000/svg" style="display:none" class="astro-xymfvnz4"> <symbol id="starlight-image-zoom-icon-zoom" viewBox="0 0 24 24" class="astro-xymfvnz4"> <path d="M9.79 12.79 4 18.59V17a1 1 0 0 0-2 0v4a1 1 0 0 0 .08.38 1 1 0 0 0 .54.54A1 1 0 0 0 3 22h4a1 1 0 0 0 0-2H5.41l5.8-5.79a1 1 0 0 0-1.42-1.42ZM21.92 2.62a1 1 0 0 0-.54-.54A1 1 0 0 0 21 2h-4a1 1 0 0 0 0 2h1.59l-5.8 5.79a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0L20 5.41V7a1 1 0 0 0 2 0V3a1 1 0 0 0-.08-.38Z" class="astro-xymfvnz4"></path> </symbol> <symbol id="starlight-image-zoom-icon-unzoom" viewBox="0 0 24 24" class="astro-xymfvnz4"> <path d="M21.71 2.29a1 1 0 0 0-1.42 0l-5.79 5.8V6.5a1 1 0 0 0-2 0v4a1 1 0 0 0 .08.38 1 1 0 0 0 .54.54 1 1 0 0 0 .38.08h4a1 1 0 0 0 0-2h-1.59l5.8-5.79a1 1 0 0 0 0-1.42ZM10.88 12.58a1 1 0 0 0-.38-.08h-4a1 1 0 0 0 0 2h1.59l-5.8 5.79a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0l5.79-5.8v1.59a1 1 0 0 0 2 0v-4a1 1 0 0 0-.08-.38 1 1 0 0 0-.54-.54Z" class="astro-xymfvnz4"></path> </symbol> </svg> </starlight-image-zoom> <script type="module" src="/_astro/ImageZoom.astro_astro_type_script_index_0_lang.CZmBqK-T.js"></script> <div class="sl-markdown-content astro-cedpceuv"> <p>Build a chat agent that streams AI responses, calls server-side tools, executes client-side tools in the browser, and asks for user approval before sensitive actions.</p> <p><strong>What you will build:</strong> A chat agent powered by Workers AI with three tool types — automatic, client-side, and approval-gated.</p> <p><strong>Time:</strong> ~15 minutes</p> <p>This tutorial starts from a minimal Hello World Worker so you can see each moving part. If you want a complete starter app with the same core pieces already wired together, start with the <a href="/agents/getting-started/quick-start/">quick start</a> and then return here to understand how the chat pieces fit together.</p> <p><strong>Prerequisites:</strong></p> <ul> <li>Node.js 18+</li> <li>A Cloudflare account (free tier works)</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="1-create-the-project">1. Create the project</h2><a class="anchor-link" href="#1-create-the-project"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.7rqu9.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">create</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">cloudflare@latest</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">chat-agent</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm create cloudflare@latest chat-agent"><div></div></button></div></figure></div> <p>Select <strong>"Hello World" Worker</strong> when prompted. Then install the dependencies:</p> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">cd</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">chat-agent</span></div></div><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">install</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">agents</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">@cloudflare/ai-chat</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">ai</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">workers-ai-provider</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">zod</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="cd chat-agentnpm install agents @cloudflare/ai-chat ai workers-ai-provider zod"><div></div></button></div></figure></div> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="2-configure-wrangler">2. Configure Wrangler</h2><a class="anchor-link" href="#2-configure-wrangler"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Replace your <code dir="auto">wrangler.jsonc</code> with:</p> <script> (() => { class StarlightTabsRestore extends HTMLElement { connectedCallback() { const starlightTabs = this.closest('starlight-tabs'); if (!(starlightTabs instanceof HTMLElement) || typeof localStorage === 'undefined') return; const syncKey = starlightTabs.dataset.syncKey; if (!syncKey) return; const label = localStorage.getItem(starlight-synced-tabs__${syncKey}); if (!label) return; const tabs = [...starlightTabs?.querySelectorAll('[role="tab"]')]; const tabIndexToRestore = tabs.findIndex( (tab) => tab instanceof HTMLAnchorElement && tab.textContent?.trim() === label ); const panels = starlightTabs?.querySelectorAll(':scope > [role="tabpanel"]'); const newTab = tabs[tabIndexToRestore]; const newPanel = panels[tabIndexToRestore]; if (tabIndexToRestore < 1 || !newTab || !newPanel) return; tabs[0]?.setAttribute('aria-selected', 'false'); tabs[0]?.setAttribute('tabindex', '-1'); panels?.[0]?.setAttribute('hidden', 'true'); newTab.removeAttribute('tabindex'); newTab.setAttribute('aria-selected', 'true'); newPanel.removeAttribute('hidden'); } } customElements.define('starlight-tabs-restore', StarlightTabsRestore); })() </script><starlight-tabs data-sync-key="wranglerConfig" class="astro-6ilsj7c3"> <div class="tablist-wrapper not-content astro-6ilsj7c3"> <ul role="tablist" class="astro-6ilsj7c3"> <li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-5260" id="tab-5260" aria-selected="true" tabindex="0" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M0.734 13.269L0.562 10.732Q1.938 10.732 2.497 10.087L2.497 10.087Q2.884 9.614 2.884 8.711L2.884 8.711Q2.884 8.324 2.798 7.571Q2.712 6.819 2.712 6.410Q2.712 6.002 2.669 5.185L2.669 5.185Q2.583 4.454 2.583 4.153L2.583 4.153Q2.583 2.089 3.787 1.099Q4.991 0.111 7.184 0.111L7.184 0.111L8.259 0.111L8.259 2.648L7.700 2.648Q6.754 2.648 6.345 3.185Q5.937 3.723 5.937 4.798L5.937 4.798Q5.937 5.056 6.023 5.572L6.023 5.572Q6.109 6.217 6.109 6.561L6.109 6.561Q6.109 6.819 6.152 7.378L6.152 7.378Q6.238 8.152 6.238 8.582L6.238 8.582Q6.238 10.216 5.550 11.033L5.550 11.033Q4.948 11.764 3.658 12.065L3.658 12.065Q4.948 12.409 5.550 13.097L5.550 13.097Q6.238 13.957 6.238 15.548L6.238 15.548Q6.238 16.021 6.152 16.795L6.152 16.795Q6.066 17.354 6.088 17.612Q6.109 17.870 6.023 18.515L6.023 18.515Q5.937 18.988 5.937 19.203L5.937 19.203Q5.937 20.278 6.345 20.815Q6.754 21.353 7.700 21.353L7.700 21.353L8.259 21.353L8.259 23.890L7.184 23.890Q2.712 23.890 2.712 19.848L2.712 19.848Q2.712 18.386 2.862 17.590Q3.013 16.795 3.013 15.290L3.013 15.290Q3.013 13.269 0.734 13.269L0.734 13.269ZM23.438 10.732L23.438 13.011Q21.159 13.011 21.159 15.032L21.159 15.032Q21.159 15.419 21.224 16.171Q21.288 16.924 21.288 17.311L21.288 17.311Q21.417 18.128 21.417 19.590L21.417 19.590Q21.417 23.632 16.859 23.632L16.859 23.632L15.784 23.632L15.784 21.353L16.300 21.353Q17.246 21.353 17.654 20.815Q18.063 20.278 18.063 19.203Q18.063 18.128 17.934 17.569L17.934 17.569Q17.934 17.225 17.848 16.558Q17.762 15.892 17.762 15.548L17.762 15.548Q17.762 13.957 18.450 13.097L18.450 13.097Q19.052 12.409 20.342 12.065L20.342 12.065Q19.052 11.764 18.450 11.033L18.450 11.033Q17.762 10.216 17.762 8.582L17.762 8.582Q17.762 8.152 17.848 7.378L17.848 7.378Q17.934 6.819 17.934 6.561L17.934 6.561Q18.063 5.873 18.063 4.841Q18.063 3.809 17.633 3.293Q17.203 2.777 16.300 2.648L16.300 2.648L15.784 2.648L15.784 0.111L16.859 0.111Q19.009 0.111 20.213 1.099Q21.417 2.089 21.417 4.153L21.417 4.153Q21.417 4.540 21.352 5.292Q21.288 6.045 21.288 6.432L21.288 6.432Q21.159 7.249 21.116 8.711L21.116 8.711Q21.159 9.614 21.503 10.087L21.503 10.087Q22.062 10.732 23.438 10.732L23.438 10.732Z"/></svg> wrangler.jsonc </a> </li><li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-5261" id="tab-5261" aria-selected="false" tabindex="-1" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="m21.32 9.55-1.89-.63.89-1.78A1 1 0 0 0 20.13 6L18 3.87a1 1 0 0 0-1.15-.19l-1.78.89-.63-1.89A1 1 0 0 0 13.5 2h-3a1 1 0 0 0-.95.68l-.63 1.89-1.78-.89A1 1 0 0 0 6 3.87L3.87 6a1 1 0 0 0-.19 1.15l.89 1.78-1.89.63a1 1 0 0 0-.68.94v3a1 1 0 0 0 .68.95l1.89.63-.89 1.78A1 1 0 0 0 3.87 18L6 20.13a1 1 0 0 0 1.15.19l1.78-.89.63 1.89a1 1 0 0 0 .95.68h3a1 1 0 0 0 .95-.68l.63-1.89 1.78.89a1 1 0 0 0 1.13-.19L20.13 18a1 1 0 0 0 .19-1.15l-.89-1.78 1.89-.63a1 1 0 0 0 .68-.94v-3a1 1 0 0 0-.68-.95ZM20 12.78l-1.2.4A2 2 0 0 0 17.64 16l.57 1.14-1.1 1.1-1.11-.6a2 2 0 0 0-2.79 1.16l-.4 1.2h-1.59l-.4-1.2A2 2 0 0 0 8 17.64l-1.14.57-1.1-1.1.6-1.11a2 2 0 0 0-1.16-2.82l-1.2-.4v-1.56l1.2-.4A2 2 0 0 0 6.36 8l-.57-1.11 1.1-1.1L8 6.36a2 2 0 0 0 2.82-1.16l.4-1.2h1.56l.4 1.2A2 2 0 0 0 16 6.36l1.14-.57 1.1 1.1-.6 1.11a2 2 0 0 0 1.16 2.79l1.2.4v1.59ZM12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4Z"/></svg> wrangler.toml </a> </li> </ul> </div> <div id="tab-panel-5260" aria-labelledby="tab-5260" role="tabpanel"> <div class="expressive-code"><link rel="stylesheet" href="/_astro/ec.7rqu9.css"><script type="module" src="/_astro/ec.0vx5m.js"></script><figure class="frame has-title not-content"><figcaption class="header"><span class="title">JSONC</span></figcaption><pre data-language="jsonc"><code><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"chat-agent"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">main</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"src/server.ts"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Set this to today's date</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">compatibility_date</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"2026-06-10"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">compatibility_flags</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"nodejs_compat"</span><span style="--0:#89DDFF;--1:#007474">],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">ai</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">binding</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"AI"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">durable_objects</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">bindings</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#F78C6C;--1:#985643">name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#F78C6C;--1:#985643">class_name</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}],</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#C895EA;--1:#7C5B92">migrations</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[{</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">tag</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#FFCB6B;--1:#7E6435">new_sqlite_classes</span><span style="--0:#89DDFF;--1:#007474">"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span><span style="--0:#89DDFF;--1:#007474">]</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}],</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="{ &#x22;name&#x22;: &#x22;chat-agent&#x22;, &#x22;main&#x22;: &#x22;src/server.ts&#x22;, // Set this to today&#x27;s date &#x22;compatibility_date&#x22;: &#x22;2026-06-10&#x22;, &#x22;compatibility_flags&#x22;: [&#x22;nodejs_compat&#x22;], &#x22;ai&#x22;: { &#x22;binding&#x22;: &#x22;AI&#x22; }, &#x22;durable_objects&#x22;: { &#x22;bindings&#x22;: [{ &#x22;name&#x22;: &#x22;ChatAgent&#x22;, &#x22;class_name&#x22;: &#x22;ChatAgent&#x22; }], }, &#x22;migrations&#x22;: [{ &#x22;tag&#x22;: &#x22;v1&#x22;, &#x22;new_sqlite_classes&#x22;: [&#x22;ChatAgent&#x22;] }],}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <div id="tab-panel-5261" aria-labelledby="tab-5261" role="tabpanel" hidden> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TOML</span></figcaption><pre data-language="toml"><code><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"chat-agent"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">main</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"src/server.ts"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic"># Set this to today's date</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">compatibility_date</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"2026-06-10"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">compatibility_flags</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"nodejs_compat"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#57C78F;--1:#00783C">ai</span><span style="--0:#89DDFF;--1:#007474">]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">binding</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"AI"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[[</span><span style="--0:#57C78F;--1:#00783C">durable_objects</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#57C78F;--1:#00783C">bindings</span><span style="--0:#89DDFF;--1:#007474">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">class_name</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">[[</span><span style="--0:#57C78F;--1:#00783C">migrations</span><span style="--0:#89DDFF;--1:#007474">]]</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">tag</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"v1"</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#00268F">new_sqlite_classes</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">[</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">]</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="name = &#x22;chat-agent&#x22;main = &#x22;src/server.ts&#x22;# Set this to today&#x27;s datecompatibility_date = &#x22;2026-06-10&#x22;compatibility_flags = [ &#x22;nodejs_compat&#x22; ][ai]binding = &#x22;AI&#x22;[[durable_objects.bindings]]name = &#x22;ChatAgent&#x22;class_name = &#x22;ChatAgent&#x22;[[migrations]]tag = &#x22;v1&#x22;new_sqlite_classes = [ &#x22;ChatAgent&#x22; ]"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <starlight-tabs-restore class="astro-6ilsj7c3"></starlight-tabs-restore> </starlight-tabs> <script type="module">class r extends HTMLElement{static#e=new Map;#t;#n="starlight-synced-tabs__";constructor(){super();const t=this.querySelector('[role="tablist"]');if(this.tabs=[...t.querySelectorAll('[role="tab"]')],this.panels=[...this.querySelectorAll(':scope > [role="tabpanel"]')],this.#t=this.dataset.syncKey,this.#t){const i=r.#e.get(this.#t)??[];i.push(this),r.#e.set(this.#t,i)}this.tabs.forEach((i,c)=>{i.addEventListener("click",e=>{e.preventDefault();const n=t.querySelector('[aria-selected="true"]');e.currentTarget!==n&&this.switchTab(e.currentTarget,c)}),i.addEventListener("keydown",e=>{const n=this.tabs.indexOf(e.currentTarget),s=e.key==="ArrowLeft"?n-1:e.key==="ArrowRight"?n+1:e.key==="Home"?0:e.key==="End"?this.tabs.length-1:null;s!==null&&this.tabs[s]&&(e.preventDefault(),this.switchTab(this.tabs[s],s))})})}switchTab(t,i,c=!0){if(!t)return;const e=c?this.getBoundingClientRect().top:0;this.tabs.forEach(s=>{s.setAttribute("aria-selected","false"),s.setAttribute("tabindex","-1")}),this.panels.forEach(s=>{s.hidden=!0});const n=this.panels[i];n&&(n.hidden=!1),t.removeAttribute("tabindex"),t.setAttribute("aria-selected","true"),c&&(t.focus(),r.#r(this,t),window.scrollTo({top:window.scrollY+(this.getBoundingClientRect().top-e),behavior:"instant"}))}#i(t){!this.#t||typeof localStorage>"u"||localStorage.setItem(this.#n+this.#t,t)}static#r(t,i){const c=t.#t,e=r.#s(i);if(!c||!e)return;const n=r.#e.get(c);if(n){for(const s of n){if(s===t)continue;const a=s.tabs.findIndex(o=>r.#s(o)===e);a!==-1&&s.switchTab(s.tabs[a],a,!1)}t.#i(e)}}static#s(t){return t.textContent?.trim()}}customElements.define("starlight-tabs",r);</script> <p>Key settings:</p> <ul> <li><code dir="auto">ai</code> binds Workers AI — no API key needed</li> <li><code dir="auto">durable_objects</code> registers your chat agent class</li> <li><code dir="auto">new_sqlite_classes</code> enables SQLite storage for message persistence</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="3-write-the-server">3. Write the server</h2><a class="anchor-link" href="#3-write-the-server"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Create <code dir="auto">src/server.ts</code>. This is where your agent lives:</p> <starlight-tabs data-sync-key="workersExamples" class="astro-6ilsj7c3"> <div class="tablist-wrapper not-content astro-6ilsj7c3"> <ul role="tablist" class="astro-6ilsj7c3"> <li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-5262" id="tab-5262" aria-selected="true" tabindex="0" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5.376 14.300L5.376 3.352L9.286 3.352L9.286 14.300Q9.286 17.842 7.630 19.452L7.630 19.452Q6.112 20.924 3.076 20.924L3.076 20.924Q2.386 20.924 1.558 20.809Q0.730 20.694 0.224 20.464L0.224 20.464L0.638 17.336Q1.512 17.750 2.662 17.750L2.662 17.750Q3.950 17.750 4.594 17.060L4.594 17.060Q5.376 16.232 5.376 14.300L5.376 14.300ZM11.862 19.912L12.736 16.600Q13.564 17.060 14.668 17.382L14.668 17.382Q15.910 17.750 17.014 17.750L17.014 17.750Q18.394 17.750 19.084 17.267Q19.774 16.784 19.774 15.910Q19.774 15.036 19.130 14.507Q18.486 13.978 16.876 13.426L16.876 13.426Q12.138 11.770 12.138 8.274L12.138 8.274Q12.138 5.974 13.909 4.525Q15.680 3.076 18.762 3.076L18.762 3.076Q21.200 3.076 23.224 3.950L23.224 3.950L22.350 7.124L22.074 6.986Q21.246 6.664 20.740 6.526L20.740 6.526Q19.774 6.250 18.762 6.250L18.762 6.250Q17.520 6.250 16.853 6.733Q16.186 7.216 16.186 7.998Q16.186 8.780 16.922 9.286L16.922 9.286Q17.474 9.700 19.314 10.436L19.314 10.436Q21.614 11.310 22.695 12.552Q23.776 13.794 23.776 15.588L23.776 15.588Q23.776 17.888 22.028 19.314L22.028 19.314Q20.142 20.924 16.738 20.924L16.738 20.924Q15.404 20.924 13.932 20.556L13.932 20.556Q12.782 20.326 11.862 19.912L11.862 19.912Z"/></svg> JavaScript </a> </li><li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-5263" id="tab-5263" aria-selected="false" tabindex="-1" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M11.376 6.833L11.532 6.833L7.359 6.833L7.359 19.235L4.317 19.235L4.317 6.833L0.183 6.833L0.183 4.610L11.376 4.610L11.376 6.833ZM20.892 15.491L20.892 15.491Q20.892 15.062 20.736 14.750Q20.580 14.438 20.307 14.126L20.307 14.126Q20.073 13.931 19.605 13.697L19.605 13.697Q19.293 13.580 18.513 13.268L18.513 13.268L18.201 13.151Q15.666 12.410 14.184 11.318L14.184 11.318Q12.858 10.187 12.858 8.510L12.858 8.510Q12.858 6.677 14.457 5.585L14.457 5.585Q15.900 4.492 18.299 4.492Q20.697 4.492 22.257 5.858L22.257 5.858Q23.700 7.145 23.700 9.017L23.700 9.017L20.892 9.017Q20.892 8.471 20.716 8.081Q20.541 7.691 20.151 7.301L20.151 7.301Q19.371 6.716 18.201 6.716Q17.031 6.716 16.407 7.184Q15.783 7.652 15.783 8.510L15.783 8.510Q15.783 9.212 16.524 9.758L16.524 9.758Q16.836 9.992 17.460 10.226L17.460 10.226Q17.928 10.421 18.942 10.733L18.942 10.733Q21.321 11.434 22.569 12.507Q23.817 13.580 23.817 15.491L23.817 15.491Q23.817 16.427 23.447 17.187Q23.076 17.948 22.374 18.416L22.374 18.416Q20.892 19.508 18.474 19.508L18.474 19.508Q15.900 19.508 14.301 18.260L14.301 18.260Q12.468 16.817 12.624 14.750L12.624 14.750L15.549 14.750Q15.549 15.998 16.407 16.700L16.407 16.700Q16.758 16.973 17.343 17.129Q17.928 17.285 18.591 17.285L18.591 17.285Q19.917 17.285 20.424 16.817L20.424 16.817Q20.892 16.076 20.892 15.491Z"/></svg> TypeScript </a> </li> </ul> </div> <div id="tab-panel-5262" aria-labelledby="tab-5262" role="tabpanel"> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">JavaScript</span></figcaption><pre data-language="js"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">AIChatAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@cloudflare/ai-chat"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">routeAgentRequest</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">createWorkersAI</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"workers-ai-provider"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">streamText</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">convertToModelMessages</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">pruneMessages</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">tool</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">stepCountIs</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"ai"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">z</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"zod"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">class</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ChatAgent</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">extends</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">AIChatAgent</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onChatMessage</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">workersai</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">createWorkersAI</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> binding</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">env</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">AI</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">result</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">streamText</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">model</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">workersai</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"@cf/meta/llama-4-scout-17b-16e-instruct"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">system</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"You are a helpful assistant. You can check the weather, "</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">+</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"get the user's timezone, and run calculations."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">messages</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">pruneMessages</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">messages</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">convertToModelMessages</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">messages</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">toolCalls</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"before-last-2-messages"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">tools</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Server-side tool: runs automatically on the server</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">getWeather</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">tool</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">description</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Get the current weather for a city"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">inputSchema</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">object</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">city</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"City name"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">execute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">city</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Replace with a real weather API in production</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">conditions</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> [</span><span style="--0:#FDDA68;--1:#A84E00">"sunny"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"cloudy"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"rainy"</span><span style="--0:#EE9080;--1:#32008F">]</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">temp</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">floor</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">random</span><span style="--0:#EE9080;--1:#32008F">() </span><span style="--0:#EE9080;--1:#8F1500"></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">30</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">+</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">5</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">city</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">temperature</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">temp</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">condition</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">conditions</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">floor</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">random</span><span style="--0:#EE9080;--1:#32008F">() </span><span style="--0:#EE9080;--1:#8F1500"></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">conditions</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EE9080;--1:#9D5600">length</span><span style="--0:#EE9080;--1:#32008F">)]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Client-side tool: no execute function — the browser handles it</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">getUserTimezone</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">tool</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">description</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Get the user's timezone from their browser"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">inputSchema</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">object</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Approval tool: requires user confirmation before executing</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">calculate</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">tool</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">description</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"Perform a math calculation with two numbers. "</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">+</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"Requires user approval for large numbers."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">inputSchema</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">object</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">a</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">coerce</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"First number"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">b</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">coerce</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"Second number"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">operator</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">z</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">enum</span><span style="--0:#EE9080;--1:#32008F">([</span><span style="--0:#FDDA68;--1:#A84E00">"+"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"-"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"/"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"%"</span><span style="--0:#EE9080;--1:#32008F">])</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"Arithmetic operator"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">needsApproval</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">a</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">b</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">abs</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">a</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">1000</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">abs</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">b</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">1000</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">execute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">a</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">b</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">operator</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">ops</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"+"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">+</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"-"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">-</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500"></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"/"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">/</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"%"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">%</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#D5D7D8;--1:#8F1500">operator</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"/"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">b</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> error</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Division by zero"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">expression</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00"></span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">a</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">operator</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">b</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"></span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">result</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">ops</span><span style="--0:#EE9080;--1:#32008F"></span><span style="--0:#D5D7D8;--1:#8F1500">operator</span><span style="--0:#EE9080;--1:#32008F"></span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">stopWhen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">stepCountIs</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#B59EE1;--1:#7C008F">5</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">result</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">toUIMessageStreamResponse</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">fetch</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">request</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">routeAgentRequest</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">request</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#EE9080;--1:#8F1500">||</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Response</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not found"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">404</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">};</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { AIChatAgent } from &#x22;@cloudflare/ai-chat&#x22;;import { routeAgentRequest } from &#x22;agents&#x22;;import { createWorkersAI } from &#x22;workers-ai-provider&#x22;;import { streamText, convertToModelMessages, pruneMessages, tool, stepCountIs,} from &#x22;ai&#x22;;import { z } from &#x22;zod&#x22;;export class ChatAgent extends AIChatAgent { async onChatMessage() { const workersai = createWorkersAI({ binding: this.env.AI }); const result = streamText({ model: workersai(&#x22;@cf/meta/llama-4-scout-17b-16e-instruct&#x22;), system: &#x22;You are a helpful assistant. You can check the weather, &#x22; + &#x22;get the user&#x27;s timezone, and run calculations.&#x22;, messages: pruneMessages({ messages: await convertToModelMessages(this.messages), toolCalls: &#x22;before-last-2-messages&#x22;, }), tools: { // Server-side tool: runs automatically on the server getWeather: tool({ description: &#x22;Get the current weather for a city&#x22;, inputSchema: z.object({ city: z.string().describe(&#x22;City name&#x22;), }), execute: async ({ city }) => { // Replace with a real weather API in production const conditions = [&#x22;sunny&#x22;, &#x22;cloudy&#x22;, &#x22;rainy&#x22;]; const temp = Math.floor(Math.random() 30) + 5; return { city, temperature: temp, condition: conditions[Math.floor(Math.random() conditions.length)], }; }, }), // Client-side tool: no execute function — the browser handles it getUserTimezone: tool({ description: &#x22;Get the user&#x27;s timezone from their browser&#x22;, inputSchema: z.object({}), }), // Approval tool: requires user confirmation before executing calculate: tool({ description: &#x22;Perform a math calculation with two numbers. &#x22; + &#x22;Requires user approval for large numbers.&#x22;, inputSchema: z.object({ a: z.coerce.number().describe(&#x22;First number&#x22;), b: z.coerce.number().describe(&#x22;Second number&#x22;), operator: z .enum([&#x22;+&#x22;, &#x22;-&#x22;, &#x22;&#x22;, &#x22;/&#x22;, &#x22;%&#x22;]) .describe(&#x22;Arithmetic operator&#x22;), }), needsApproval: async ({ a, b }) => Math.abs(a) > 1000 || Math.abs(b) > 1000, execute: async ({ a, b, operator }) => { const ops = { &#x22;+&#x22;: (x, y) => x + y, &#x22;-&#x22;: (x, y) => x - y, &#x22;&#x22;: (x, y) => x y, &#x22;/&#x22;: (x, y) => x / y, &#x22;%&#x22;: (x, y) => x % y, }; if (operator === &#x22;/&#x22; &#x26;&#x26; b === 0) { return { error: &#x22;Division by zero&#x22; }; } return { expression: &#x60;${a} ${operator} ${b}&#x60;, result: opsoperator, }; }, }), }, stopWhen: stepCountIs(5), }); return result.toUIMessageStreamResponse(); }}export default { async fetch(request, env) { return ( (await routeAgentRequest(request, env)) || new Response(&#x22;Not found&#x22;, { status: 404 }) ); },};"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <div id="tab-panel-5263" aria-labelledby="tab-5263" role="tabpanel" hidden> <div class="expressive-code"><figure class="frame has-title not-content"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">AIChatAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@cloudflare/ai-chat"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">routeAgentRequest</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">createWorkersAI</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"workers-ai-provider"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">streamText</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">convertToModelMessages</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">pruneMessages</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">tool</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">stepCountIs</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"ai"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">z</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"zod"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">class</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ChatAgent</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">extends</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">AIChatAgent</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onChatMessage</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">workersai</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">createWorkersAI</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> binding</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">env</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">AI</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">result</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">streamText</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">model</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">workersai</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"@cf/meta/llama-4-scout-17b-16e-instruct"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">system</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"You are a helpful assistant. You can check the weather, "</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">+</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"get the user's timezone, and run calculations."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">messages</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">pruneMessages</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">messages</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">convertToModelMessages</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">messages</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">toolCalls</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"before-last-2-messages"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">tools</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Server-side tool: runs automatically on the server</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">getWeather</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">tool</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">description</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Get the current weather for a city"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">inputSchema</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">object</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">city</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"City name"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">execute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">city</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Replace with a real weather API in production</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">conditions</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> [</span><span style="--0:#FDDA68;--1:#A84E00">"sunny"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"cloudy"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"rainy"</span><span style="--0:#EE9080;--1:#32008F">]</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">temp</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">floor</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">random</span><span style="--0:#EE9080;--1:#32008F">() </span><span style="--0:#EE9080;--1:#8F1500"></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">30</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">+</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">5</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">city</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">temperature</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">temp</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">condition</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">conditions</span><span style="--0:#EE9080;--1:#32008F">[</span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">floor</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">random</span><span style="--0:#EE9080;--1:#32008F">() </span><span style="--0:#EE9080;--1:#8F1500"></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">conditions</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EE9080;--1:#9D5600">length</span><span style="--0:#EE9080;--1:#32008F">)]</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Client-side tool: no execute function — the browser handles it</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">getUserTimezone</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">tool</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">description</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Get the user's timezone from their browser"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">inputSchema</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">object</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Approval tool: requires user confirmation before executing</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">calculate</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">tool</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">description</span><span style="--0:#89DDFF;--1:#007474">:</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"Perform a math calculation with two numbers. "</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">+</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"Requires user approval for large numbers."</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">inputSchema</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">object</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">a</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">coerce</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"First number"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">b</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">z</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">coerce</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"Second number"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">operator</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">z</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">enum</span><span style="--0:#EE9080;--1:#32008F">([</span><span style="--0:#FDDA68;--1:#A84E00">"+"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"-"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"/"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"%"</span><span style="--0:#EE9080;--1:#32008F">])</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">describe</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"Arithmetic operator"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">needsApproval</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">a</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">b</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">abs</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">a</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">1000</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">||</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">Math</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">abs</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">b</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">1000</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">execute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">a</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">b</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">operator</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">ops</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Record</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--1:#007474"><span style="--0:#89DDFF">,</span><span style="--0:#EE9080"> </span><span style="--0:#89DDFF">(</span></span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--1:#007474"><span style="--0:#89DDFF">,</span><span style="--0:#EE9080"> </span></span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--1:#007474"><span style="--0:#89DDFF">)</span><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">number</span><span style="--1:#007474"><span style="--0:#89DDFF">></span><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"+"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">+</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"-"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">-</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500"></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"/"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">/</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"%"</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">x</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">y</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">x</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">%</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">y</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#D5D7D8;--1:#8F1500">operator</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"/"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">b</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">0</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> error</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"Division by zero"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">expression</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00"></span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">a</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">operator</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"> </span><span style="--0:#89DDFF;--1:#007474">${</span><span style="--0:#D5D7D8;--1:#8F1500">b</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#FDDA68;--1:#A84E00"></span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">result</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">ops</span><span style="--0:#EE9080;--1:#32008F"></span><span style="--0:#D5D7D8;--1:#8F1500">operator</span><span style="--0:#EE9080;--1:#32008F"></span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">};</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">stopWhen</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">stepCountIs</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#B59EE1;--1:#7C008F">5</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">result</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">toUIMessageStreamResponse</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">fetch</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">request</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Request</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">env</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#EE9080;--1:#8F1500">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">routeAgentRequest</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">request</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">env</span><span style="--0:#EEFFFF;--1:#62676A">)) </span><span style="--0:#EE9080;--1:#8F1500">||</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Response</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">"Not found"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> status</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">404</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">satisfies</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ExportedHandler</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">Env</span><span style="--0:#89DDFF;--1:#007474">>;</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { AIChatAgent } from &#x22;@cloudflare/ai-chat&#x22;;import { routeAgentRequest } from &#x22;agents&#x22;;import { createWorkersAI } from &#x22;workers-ai-provider&#x22;;import { streamText, convertToModelMessages, pruneMessages, tool, stepCountIs,} from &#x22;ai&#x22;;import { z } from &#x22;zod&#x22;;export class ChatAgent extends AIChatAgent { async onChatMessage() { const workersai = createWorkersAI({ binding: this.env.AI }); const result = streamText({ model: workersai(&#x22;@cf/meta/llama-4-scout-17b-16e-instruct&#x22;), system: &#x22;You are a helpful assistant. You can check the weather, &#x22; + &#x22;get the user&#x27;s timezone, and run calculations.&#x22;, messages: pruneMessages({ messages: await convertToModelMessages(this.messages), toolCalls: &#x22;before-last-2-messages&#x22;, }), tools: { // Server-side tool: runs automatically on the server getWeather: tool({ description: &#x22;Get the current weather for a city&#x22;, inputSchema: z.object({ city: z.string().describe(&#x22;City name&#x22;), }), execute: async ({ city }) => { // Replace with a real weather API in production const conditions = [&#x22;sunny&#x22;, &#x22;cloudy&#x22;, &#x22;rainy&#x22;]; const temp = Math.floor(Math.random() 30) + 5; return { city, temperature: temp, condition: conditions[Math.floor(Math.random() conditions.length)], }; }, }), // Client-side tool: no execute function — the browser handles it getUserTimezone: tool({ description: &#x22;Get the user&#x27;s timezone from their browser&#x22;, inputSchema: z.object({}), }), // Approval tool: requires user confirmation before executing calculate: tool({ description: &#x22;Perform a math calculation with two numbers. &#x22; + &#x22;Requires user approval for large numbers.&#x22;, inputSchema: z.object({ a: z.coerce.number().describe(&#x22;First number&#x22;), b: z.coerce.number().describe(&#x22;Second number&#x22;), operator: z .enum([&#x22;+&#x22;, &#x22;-&#x22;, &#x22;&#x22;, &#x22;/&#x22;, &#x22;%&#x22;]) .describe(&#x22;Arithmetic operator&#x22;), }), needsApproval: async ({ a, b }) => Math.abs(a) > 1000 || Math.abs(b) > 1000, execute: async ({ a, b, operator }) => { const ops: Record<string, (x: number, y: number) => number> = { &#x22;+&#x22;: (x, y) => x + y, &#x22;-&#x22;: (x, y) => x - y, &#x22;&#x22;: (x, y) => x y, &#x22;/&#x22;: (x, y) => x / y, &#x22;%&#x22;: (x, y) => x % y, }; if (operator === &#x22;/&#x22; &#x26;&#x26; b === 0) { return { error: &#x22;Division by zero&#x22; }; } return { expression: &#x60;${a} ${operator} ${b}&#x60;, result: opsoperator, }; }, }), }, stopWhen: stepCountIs(5), }); return result.toUIMessageStreamResponse(); }}export default { async fetch(request: Request, env: Env) { return ( (await routeAgentRequest(request, env)) || new Response(&#x22;Not found&#x22;, { status: 404 }) ); },} satisfies ExportedHandler<Env>;"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <starlight-tabs-restore class="astro-6ilsj7c3"></starlight-tabs-restore> </starlight-tabs> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="what-each-tool-type-does">What each tool type does</h3><a class="anchor-link" href="#what-each-tool-type-does"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <table><thead><tr><th>Tool</th><th><code dir="auto">execute</code>?</th><th><code dir="auto">needsApproval</code>?</th><th>Behavior</th></tr></thead><tbody><tr><td><code dir="auto">getWeather</code></td><td>Yes</td><td>No</td><td>Runs on the server automatically</td></tr><tr><td><code dir="auto">getUserTimezone</code></td><td>No</td><td>No</td><td>Sent to the client; browser provides the result</td></tr><tr><td><code dir="auto">calculate</code></td><td>Yes</td><td>Yes (large numbers)</td><td>Pauses for user approval, then runs on server</td></tr></tbody></table> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="4-write-the-client">4. Write the client</h2><a class="anchor-link" href="#4-write-the-client"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Create <code dir="auto">src/client.tsx</code>:</p> <starlight-tabs data-sync-key="workersExamples" class="astro-6ilsj7c3"> <div class="tablist-wrapper not-content astro-6ilsj7c3"> <ul role="tablist" class="astro-6ilsj7c3"> <li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-5264" id="tab-5264" aria-selected="true" tabindex="0" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M5.376 14.300L5.376 3.352L9.286 3.352L9.286 14.300Q9.286 17.842 7.630 19.452L7.630 19.452Q6.112 20.924 3.076 20.924L3.076 20.924Q2.386 20.924 1.558 20.809Q0.730 20.694 0.224 20.464L0.224 20.464L0.638 17.336Q1.512 17.750 2.662 17.750L2.662 17.750Q3.950 17.750 4.594 17.060L4.594 17.060Q5.376 16.232 5.376 14.300L5.376 14.300ZM11.862 19.912L12.736 16.600Q13.564 17.060 14.668 17.382L14.668 17.382Q15.910 17.750 17.014 17.750L17.014 17.750Q18.394 17.750 19.084 17.267Q19.774 16.784 19.774 15.910Q19.774 15.036 19.130 14.507Q18.486 13.978 16.876 13.426L16.876 13.426Q12.138 11.770 12.138 8.274L12.138 8.274Q12.138 5.974 13.909 4.525Q15.680 3.076 18.762 3.076L18.762 3.076Q21.200 3.076 23.224 3.950L23.224 3.950L22.350 7.124L22.074 6.986Q21.246 6.664 20.740 6.526L20.740 6.526Q19.774 6.250 18.762 6.250L18.762 6.250Q17.520 6.250 16.853 6.733Q16.186 7.216 16.186 7.998Q16.186 8.780 16.922 9.286L16.922 9.286Q17.474 9.700 19.314 10.436L19.314 10.436Q21.614 11.310 22.695 12.552Q23.776 13.794 23.776 15.588L23.776 15.588Q23.776 17.888 22.028 19.314L22.028 19.314Q20.142 20.924 16.738 20.924L16.738 20.924Q15.404 20.924 13.932 20.556L13.932 20.556Q12.782 20.326 11.862 19.912L11.862 19.912Z"/></svg> JavaScript </a> </li><li role="presentation" class="tab astro-6ilsj7c3"> <a role="tab" href="#tab-panel-5265" id="tab-5265" aria-selected="false" tabindex="-1" class="astro-6ilsj7c3"> <svg aria-hidden="true" class="astro-6ilsj7c3 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M11.376 6.833L11.532 6.833L7.359 6.833L7.359 19.235L4.317 19.235L4.317 6.833L0.183 6.833L0.183 4.610L11.376 4.610L11.376 6.833ZM20.892 15.491L20.892 15.491Q20.892 15.062 20.736 14.750Q20.580 14.438 20.307 14.126L20.307 14.126Q20.073 13.931 19.605 13.697L19.605 13.697Q19.293 13.580 18.513 13.268L18.513 13.268L18.201 13.151Q15.666 12.410 14.184 11.318L14.184 11.318Q12.858 10.187 12.858 8.510L12.858 8.510Q12.858 6.677 14.457 5.585L14.457 5.585Q15.900 4.492 18.299 4.492Q20.697 4.492 22.257 5.858L22.257 5.858Q23.700 7.145 23.700 9.017L23.700 9.017L20.892 9.017Q20.892 8.471 20.716 8.081Q20.541 7.691 20.151 7.301L20.151 7.301Q19.371 6.716 18.201 6.716Q17.031 6.716 16.407 7.184Q15.783 7.652 15.783 8.510L15.783 8.510Q15.783 9.212 16.524 9.758L16.524 9.758Q16.836 9.992 17.460 10.226L17.460 10.226Q17.928 10.421 18.942 10.733L18.942 10.733Q21.321 11.434 22.569 12.507Q23.817 13.580 23.817 15.491L23.817 15.491Q23.817 16.427 23.447 17.187Q23.076 17.948 22.374 18.416L22.374 18.416Q20.892 19.508 18.474 19.508L18.474 19.508Q15.900 19.508 14.301 18.260L14.301 18.260Q12.468 16.817 12.624 14.750L12.624 14.750L15.549 14.750Q15.549 15.998 16.407 16.700L16.407 16.700Q16.758 16.973 17.343 17.129Q17.928 17.285 18.591 17.285L18.591 17.285Q19.917 17.285 20.424 16.817L20.424 16.817Q20.892 16.076 20.892 15.491Z"/></svg> TypeScript </a> </li> </ul> </div> <div id="tab-panel-5264" aria-labelledby="tab-5264" role="tabpanel"> <div class="expressive-code"><figure class="frame has-title not-content" style="--lnWidth:3ch"><figcaption class="header"><span class="title">JavaScript</span></figcaption><pre data-language="js"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents/react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useAgentChat</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">getToolApproval</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@cloudflare/ai-chat/react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chat</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">agent</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgent</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> agent</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">messages</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">sendMessage</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">clearHistory</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">addToolApprovalResponse</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgentChat</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">agent</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Handle client-side tools (tools with no server execute function)</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">onToolCall</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">toolCall</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">addToolOutput</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#EEFFFF;--1:#00268F">toolCall</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolName</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"getUserTimezone"</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">addToolOutput</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">toolCallId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">toolCall</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolCallId</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">output</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">timezone</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">Intl</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">DateTimeFormat</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">resolvedOptions</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">timeZone</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">localTime</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">Date</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">toLocaleTimeString</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#00268F">messages</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">map</span><span style="--0:#89DDFF;--1:#007474">((</span><span style="--0:#B59EE1;--1:#7C008F">msg</span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">key</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#00268F">msg</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#89DDFF;--1:#007474">}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">strong</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#EEFFFF;--1:#00268F">msg</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</span><span style="--0:#89DDFF;--1:#007474">}:&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">strong</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#00268F">msg</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">parts</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">map</span><span style="--0:#89DDFF;--1:#007474">((</span><span style="--0:#B59EE1;--1:#7C008F">part</span><span style="--0:#89DDFF;--1:#007474">, </span><span style="--0:#B59EE1;--1:#7C008F">i</span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#89DDFF;--1:#007474"> {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#89DDFF;--1:#007474"> (</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">type</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"text"</span><span style="--0:#89DDFF;--1:#007474">) {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474"> &#x3C;</span><span style="--0:#F38B90;--1:#A54E53">span</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">key</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">i</span><span style="--0:#89DDFF;--1:#007474">}>{</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">text</span><span style="--0:#89DDFF;--1:#007474">}&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">span</span><span style="--0:#89DDFF;--1:#007474">>;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Render approval UI for tools that need confirmation</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#89DDFF;--1:#007474"> (</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"approval-requested"</span><span style="--0:#89DDFF;--1:#007474">) {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">approval</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getToolApproval</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">part</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#89DDFF;--1:#007474"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">approval</span></span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">key</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolCallId</span><span style="--0:#89DDFF;--1:#007474">}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Approve &#x3C;</span><span style="--0:#F38B90;--1:#A54E53">strong</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolName</span><span style="--0:#89DDFF;--1:#007474">}&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">strong</span><span style="--0:#89DDFF;--1:#007474">>?</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">p</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">pre</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#EEFFFF;--1:#00268F">JSON</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">stringify</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#89DDFF;--1:#007474">, </span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#89DDFF;--1:#007474">, </span><span style="--0:#B59EE1;--1:#7C008F">2</span><span style="--0:#89DDFF;--1:#007474">)}&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">pre</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{() </span><span style="--0:#EE9080;--1:#8F1500">=></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">addToolApprovalResponse</span><span style="--0:#89DDFF;--1:#007474">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">id: </span><span style="--0:#EEFFFF;--1:#00268F">approval</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">approved: </span><span style="--0:#EE9080;--1:#32008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">})</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Approve</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">button</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{() </span><span style="--0:#EE9080;--1:#8F1500">=></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">addToolApprovalResponse</span><span style="--0:#89DDFF;--1:#007474">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">id: </span><span style="--0:#EEFFFF;--1:#00268F">approval</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">approved: </span><span style="--0:#EE9080;--1:#32008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">})</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Reject</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Show completed tool results</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#89DDFF;--1:#007474"> (</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"output-available"</span><span style="--0:#89DDFF;--1:#007474">) {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">details</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">key</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolCallId</span><span style="--0:#89DDFF;--1:#007474">}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">summary</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolName</span><span style="--0:#89DDFF;--1:#007474">} result&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">summary</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">pre</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#EEFFFF;--1:#00268F">JSON</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">stringify</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">output</span><span style="--0:#89DDFF;--1:#007474">, </span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#89DDFF;--1:#007474">, </span><span style="--0:#B59EE1;--1:#7C008F">2</span><span style="--0:#89DDFF;--1:#007474">)}&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">pre</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">details</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">})}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">))}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">form</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#C895EA;--1:#7C5B92">onSubmit</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{(</span><span style="--0:#B59EE1;--1:#7C008F">e</span><span style="--0:#89DDFF;--1:#007474">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#89DDFF;--1:#007474"> {</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">e</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">preventDefault</span><span style="--0:#89DDFF;--1:#007474">();</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">e</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">currentTarget</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">elements</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">namedItem</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#FDDA68;--1:#A84E00">"message"</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">sendMessage</span><span style="--0:#89DDFF;--1:#007474">({ text: </span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">value</span><span style="--0:#89DDFF;--1:#007474"> });</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">value</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">input</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">name</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#FDDA68;--1:#A84E00">"message"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">placeholder</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#FDDA68;--1:#A84E00">"Try: What's the weather in Paris?"</span><span style="--0:#89DDFF;--1:#007474"> /></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">type</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#FDDA68;--1:#A84E00">"submit"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">disabled</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#FDDA68;--1:#A84E00">"streaming"</span><span style="--0:#89DDFF;--1:#007474">}></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">Send</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">form</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#C895EA;--1:#7C5B92">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">clearHistory</span><span style="--0:#89DDFF;--1:#007474">}>Clear history&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">button</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#89DDFF;--1:#007474"> </span></span><span style="--0:#89DDFF;--1:#007474">&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">div</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">App</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">Chat</span><span style="--0:#89DDFF;--1:#007474"> />;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { useAgent } from &#x22;agents/react&#x22;;import { useAgentChat, getToolApproval } from &#x22;@cloudflare/ai-chat/react&#x22;;function Chat() { const agent = useAgent({ agent: &#x22;ChatAgent&#x22; }); const { messages, sendMessage, clearHistory, addToolApprovalResponse, status, } = useAgentChat({ agent, // Handle client-side tools (tools with no server execute function) onToolCall: async ({ toolCall, addToolOutput }) => { if (toolCall.toolName === &#x22;getUserTimezone&#x22;) { addToolOutput({ toolCallId: toolCall.toolCallId, output: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, localTime: new Date().toLocaleTimeString(), }, }); } }, }); return ( <div> <div> {messages.map((msg) => ( <div key={msg.id}> <strong>{msg.role}:</strong> {msg.parts.map((part, i) => { if (part.type === &#x22;text&#x22;) { return <span key={i}>{part.text}</span>; } // Render approval UI for tools that need confirmation if (part.state === &#x22;approval-requested&#x22;) { const approval = getToolApproval(part); if (!approval) return null; return ( <div key={part.toolCallId}> <p> Approve <strong>{part.toolName}</strong>? </p> <pre>{JSON.stringify(part.input, null, 2)}</pre> <button onClick={() => addToolApprovalResponse({ id: approval.id, approved: true, }) } > Approve </button> <button onClick={() => addToolApprovalResponse({ id: approval.id, approved: false, }) } > Reject </button> </div> ); } // Show completed tool results if (part.state === &#x22;output-available&#x22;) { return ( <details key={part.toolCallId}> <summary>{part.toolName} result</summary> <pre>{JSON.stringify(part.output, null, 2)}</pre> </details> ); } return null; })} </div> ))} </div> <form onSubmit={(e) => { e.preventDefault(); const input = e.currentTarget.elements.namedItem(&#x22;message&#x22;); sendMessage({ text: input.value }); input.value = &#x22;&#x22;; }} > <input name=&#x22;message&#x22; placeholder=&#x22;Try: What&#x27;s the weather in Paris?&#x22; /> <button type=&#x22;submit&#x22; disabled={status === &#x22;streaming&#x22;}> Send </button> </form> <button onClick={clearHistory}>Clear history</button> </div> );}export default function App() { return <Chat />;}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <div id="tab-panel-5265" aria-labelledby="tab-5265" role="tabpanel" hidden> <div class="expressive-code"><figure class="frame has-title not-content" style="--lnWidth:3ch"><figcaption class="header"><span class="title">TypeScript</span></figcaption><pre data-language="ts"><code><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useAgent</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"agents/react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">import </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">useAgentChat</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">getToolApproval</span><span style="--0:#EE9080"> </span></span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500"> from </span><span style="--0:#FDDA68;--1:#A84E00">"@cloudflare/ai-chat/react"</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">Chat</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">agent</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">useAgent</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> agent</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"ChatAgent"</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">messages</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">sendMessage</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">clearHistory</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">addToolApprovalResponse</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">status</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">useAgentChat</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">agent</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Handle client-side tools (tools with no server execute function)</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">onToolCall</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">({</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">toolCall</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#B59EE1;--1:#7C008F">addToolOutput</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">})</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EE9080;--1:#32008F"> (</span><span style="--0:#EEFFFF;--1:#00268F">toolCall</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolName</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"getUserTimezone"</span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">addToolOutput</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">toolCallId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">toolCall</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">toolCallId</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">output</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">timezone</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">Intl</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">DateTimeFormat</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">resolvedOptions</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">timeZone</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">localTime</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">new</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">Date</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">toLocaleTimeString</span><span style="--0:#EE9080;--1:#32008F">()</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">},</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">div</span><span style="--0:#EEFFFF;--1:#62676A">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">div</span><span style="--0:#EEFFFF;--1:#62676A">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#B59EE1;--1:#7C008F">messages</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">map</span><span style="--0:#EEFFFF;--1:#62676A">((</span><span style="--0:#B59EE1;--1:#7C008F">msg</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">div</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">key</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">msg.</span><span style="--0:#D5D7D8;--1:#8F1500">id</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">strong</span><span style="--0:#EEFFFF;--1:#62676A">></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">msg.</span><span style="--0:#D5D7D8;--1:#8F1500">role</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--1:#007474"><span style="--0:#89DDFF">&#x3C;</span><span style="--0:#EEFFFF">/</span></span><span style="--0:#57C78F;--1:#00783C">strong</span><span style="--0:#89DDFF;--1:#007474">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#B59EE1;--1:#7C008F">msg</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">parts</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">map</span><span style="--0:#EEFFFF;--1:#62676A">((</span><span style="--0:#B59EE1;--1:#7C008F">part</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">i</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">=></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">if</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#EEFFFF;--1:#62676A">part.type === </span><span style="--0:#FDDA68;--1:#A84E00">"text"</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> &#x3C;</span><span style="--0:#57C78F;--1:#00783C">span</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">key</span><span style="--0:#EEFFFF;--1:#62676A">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#00268F">i</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">part.</span><span style="--0:#D5D7D8;--1:#8F1500">text</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">span</span><span style="--0:#EE9080">></span></span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Render approval UI for tools that need confirmation</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">if</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#EEFFFF;--1:#62676A">part.state === </span><span style="--0:#FDDA68;--1:#A84E00">"approval-requested"</span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">approval</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">getToolApproval</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">part</span><span style="--0:#EE9080;--1:#32008F">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--1:#8F1500"><span style="--0:#EE9080">!</span><span style="--0:#D5D7D8">approval</span></span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> (</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">div</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">key</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">part.</span><span style="--0:#D5D7D8;--1:#8F1500">toolCallId</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">p</span><span style="--0:#EEFFFF;--1:#62676A">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">Approve</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">strong</span><span style="--0:#EE9080">></span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">part.</span><span style="--0:#D5D7D8;--1:#8F1500">toolName</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">strong</span><span style="--0:#EE9080">>?</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">p</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#57C78F;--1:#00783C">pre</span><span style="--0:#EEFFFF;--1:#62676A">></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">JSON.stringify(part.</span><span style="--0:#D5D7D8;--1:#8F1500">input</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">null</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">2</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">pre</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">button</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">onClick</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">() =></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">addToolApprovalResponse</span><span style="--0:#89DDFF;--1:#007474">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">approval</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">id</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">approved</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">true</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">})</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">Approve</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">button</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">button</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">onClick</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">() =></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">addToolApprovalResponse</span><span style="--0:#89DDFF;--1:#007474">({</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">id</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">approval</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">id</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">approved</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">false</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">})</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">Reject</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">button</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">div</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">);</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#A9A9A5;--0fs:italic;--1:#62676A;--1fs:italic">// Show completed tool results</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">part</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">state</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"output-available"</span><span style="--0:#EEFFFF;--1:#62676A">) </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#B59EE1;--1:#7C008F">details</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">key</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">part.</span><span style="--0:#D5D7D8;--1:#8F1500">toolCallId</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#B59EE1;--1:#7C008F">summary</span><span style="--0:#EEFFFF;--1:#62676A">></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#B59EE1;--1:#7C008F">part</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">toolName</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">result</span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;/</span><span style="--0:#B59EE1;--1:#7C008F">summary</span><span style="--0:#EEFFFF;--1:#62676A">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;</span><span style="--0:#B59EE1;--1:#7C008F">pre</span><span style="--0:#EEFFFF;--1:#62676A">></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#B59EE1;--1:#7C008F">JSON</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">stringify</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#B59EE1;--1:#7C008F">part</span><span style="--0:#EEFFFF;--1:#62676A">.</span><span style="--0:#B59EE1;--1:#7C008F">output</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">null</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> 2)</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;/</span><span style="--0:#B59EE1;--1:#7C008F">pre</span><span style="--0:#EEFFFF;--1:#62676A">></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">&#x3C;/</span><span style="--0:#B59EE1;--1:#7C008F">details</span><span style="--0:#EEFFFF;--1:#62676A">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">)</span><span style="--0:#EEFFFF;--1:#62676A">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#32008F">null</span><span style="--0:#EEFFFF;--1:#62676A">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">})}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">div</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">))}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">div</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">form</span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">onSubmit</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A">(e) => </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">e</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">preventDefault</span><span style="--0:#EEFFFF;--1:#62676A">()</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">e</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">currentTarget</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">elements</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">namedItem</span><span style="--0:#EE9080;--1:#32008F">(</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#FDDA68;--1:#A84E00">"message"</span><span style="--0:#89DDFF;--1:#007474">,</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">) </span><span style="--0:#EE9080;--1:#8F1500">as</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#57C78F;--1:#00783C">HTMLInputElement</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#57C78F;--1:#00783C">sendMessage</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#EEFFFF;--1:#62676A"> text</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">value</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EEFFFF;--1:#62676A">)</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">input</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">value</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">""</span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#89DDFF;--1:#007474">}}</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">input</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">name</span><span style="--0:#EE9080">=</span></span><span style="--0:#FDDA68;--1:#A84E00">"message"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">placeholder</span><span style="--0:#EE9080">=</span></span><span style="--0:#FDDA68;--1:#A84E00">"Try: What's the weather in Paris?"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">/></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">button</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">type</span><span style="--0:#EE9080">=</span></span><span style="--0:#FDDA68;--1:#A84E00">"submit"</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">disabled</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">status</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">===</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"streaming"</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--0:#EE9080;--1:#8F1500">></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#D5D7D8;--1:#8F1500">Send</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">button</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">form</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;</span><span style="--0:#D5D7D8">button</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">onClick</span><span style="--0:#EE9080">=</span></span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">clearHistory</span><span style="--0:#89DDFF;--1:#007474">}</span><span style="--1:#8F1500"><span style="--0:#EE9080">></span><span style="--0:#D5D7D8">Clear</span></span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--1:#8F1500"><span style="--0:#D5D7D8">history</span><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">button</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--1:#8F1500"><span style="--0:#EE9080">&#x3C;/</span><span style="--0:#D5D7D8">div</span><span style="--0:#EE9080">></span></span></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EEFFFF;--1:#62676A"> </span></span><span style="--0:#EEFFFF;--1:#62676A">);</span></div></div><div class="ec-line"><div class="code"><span style="--0:#EEFFFF;--1:#62676A">}</span></div></div><div class="ec-line"><div class="code"> </div></div><div class="ec-line"><div class="code"><span style="--0:#D5D7D8;--1:#8F1500">export</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#D5D7D8;--1:#8F1500">default</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">function</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">App</span><span style="--0:#89DDFF;--1:#007474">()</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#89DDFF;--1:#007474">{</span></div></div><div class="ec-line"><div class="code"><span class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">return</span><span style="--0:#EEFFFF;--1:#62676A"> &#x3C;</span><span style="--0:#57C78F;--1:#00783C">Chat</span><span style="--0:#EEFFFF;--1:#62676A"> /></span><span style="--0:#89DDFF;--1:#007474">;</span></div></div><div class="ec-line"><div class="code"><span style="--0:#89DDFF;--1:#007474">}</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { useAgent } from &#x22;agents/react&#x22;;import { useAgentChat, getToolApproval } from &#x22;@cloudflare/ai-chat/react&#x22;;function Chat() { const agent = useAgent({ agent: &#x22;ChatAgent&#x22; }); const { messages, sendMessage, clearHistory, addToolApprovalResponse, status } = useAgentChat({ agent, // Handle client-side tools (tools with no server execute function) onToolCall: async ({ toolCall, addToolOutput }) => { if (toolCall.toolName === &#x22;getUserTimezone&#x22;) { addToolOutput({ toolCallId: toolCall.toolCallId, output: { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, localTime: new Date().toLocaleTimeString(), }, }); } }, }); return ( <div> <div> {messages.map((msg) => ( <div key={msg.id}> <strong>{msg.role}:</strong> {msg.parts.map((part, i) => { if (part.type === &#x22;text&#x22;) { return <span key={i}>{part.text}</span>; } // Render approval UI for tools that need confirmation if (part.state === &#x22;approval-requested&#x22;) { const approval = getToolApproval(part); if (!approval) return null; return ( <div key={part.toolCallId}> <p> Approve <strong>{part.toolName}</strong>? </p> <pre>{JSON.stringify(part.input, null, 2)}</pre> <button onClick={() => addToolApprovalResponse({ id: approval.id, approved: true, }) } > Approve </button> <button onClick={() => addToolApprovalResponse({ id: approval.id, approved: false, }) } > Reject </button> </div> ); } // Show completed tool results if (part.state === &#x22;output-available&#x22;) { return ( <details key={part.toolCallId}> <summary>{part.toolName} result</summary> <pre>{JSON.stringify(part.output, null, 2)}</pre> </details> ); } return null; })} </div> ))} </div> <form onSubmit={(e) => { e.preventDefault(); const input = e.currentTarget.elements.namedItem( &#x22;message&#x22;, ) as HTMLInputElement; sendMessage({ text: input.value }); input.value = &#x22;&#x22;; }} > <input name=&#x22;message&#x22; placeholder=&#x22;Try: What&#x27;s the weather in Paris?&#x22; /> <button type=&#x22;submit&#x22; disabled={status === &#x22;streaming&#x22;}> Send </button> </form> <button onClick={clearHistory}>Clear history</button> </div> );}export default function App() { return <Chat />;}"><div></div></button></div><div class="explain"><button class="explain-button" type="button" data-explain-code="" aria-label="Explain Code"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path><path d="M20 3v4"></path><path d="M22 5h-4"></path><path d="M4 17v2"></path><path d="M5 18H3"></path></svg></button></div></figure></div> </div> <starlight-tabs-restore class="astro-6ilsj7c3"></starlight-tabs-restore> </starlight-tabs> <div tabindex="-1" class="heading-wrapper level-h3"><h3 id="key-client-concepts">Key client concepts</h3><a class="anchor-link" href="#key-client-concepts"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <ul> <li><strong><code dir="auto">useAgent</code></strong> connects to your <code dir="auto">ChatAgent</code> over WebSocket</li> <li><strong><code dir="auto">useAgentChat</code></strong> manages the chat lifecycle (messages, streaming, tools)</li> <li><strong><code dir="auto">onToolCall</code></strong> handles client-side tools — when the LLM calls <code dir="auto">getUserTimezone</code>, the browser provides the result and the conversation auto-continues</li> <li><strong><code dir="auto">addToolApprovalResponse</code></strong> approves or rejects tools that have <code dir="auto">needsApproval</code></li> <li>Messages, streaming, and resumption are all handled automatically</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="5-run-locally">5. Run locally</h2><a class="anchor-link" href="#5-run-locally"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Generate types and start the dev server:</p> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npx</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">wrangler</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">types</span></div></div><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npm</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">run</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">dev</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npx wrangler typesnpm run dev"><div></div></button></div></figure></div> <p>Try these prompts:</p> <ul> <li><strong>"What is the weather in Tokyo?"</strong> — calls the server-side <code dir="auto">getWeather</code> tool</li> <li><strong>"What timezone am I in?"</strong> — calls the client-side <code dir="auto">getUserTimezone</code> tool (the browser provides the answer)</li> <li><strong>"What is 5000 times 3?"</strong> — triggers the approval UI before executing (numbers over 1000)</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="6-deploy">6. Deploy</h2><a class="anchor-link" href="#6-deploy"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div class="expressive-code"><figure class="frame is-terminal not-content"><figcaption class="header"><span class="title"></span><span class="sr-only">Terminal window</span></figcaption><pre data-language="sh"><code><div class="ec-line"><div class="code"><span style="--0:#57C78F;--1:#00783C">npx</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">wrangler</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">deploy</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npx wrangler deploy"><div></div></button></div></figure></div> <p>Your agent is now live on Cloudflare's global network. Messages persist in SQLite, streams resume on disconnect, and the agent hibernates when idle to save resources.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="what-you-built">What you built</h2><a class="anchor-link" href="#what-you-built"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <p>Your chat agent has:</p> <ul> <li><strong>Streaming AI responses</strong> via Workers AI (no API keys)</li> <li><strong>Message persistence</strong> in SQLite — conversations survive restarts</li> <li><strong>Server-side tools</strong> that execute automatically</li> <li><strong>Client-side tools</strong> that run in the browser and feed results back to the LLM</li> <li><strong>Human-in-the-loop approval</strong> for sensitive operations</li> <li><strong>Resumable streaming</strong> — if a client disconnects mid-stream, it picks up where it left off</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="next-steps">Next steps</h2><a class="anchor-link" href="#next-steps"><span aria-hidden="true" class="anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span></a></div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/agents/communication-channels/chat/chat-agents/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Chat agents API reference</span> </a> <span class="description astro-lyux3snc">Full reference for AIChatAgent and useAgentChat — providers, storage, advanced patterns.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/agents/runtime/lifecycle/state/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Store and sync state</span> </a> <span class="description astro-lyux3snc">Add real-time state beyond chat messages.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/agents/runtime/lifecycle/callable-methods/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Callable methods</span> </a> <span class="description astro-lyux3snc">Expose agent methods as typed RPC for your client.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg> </div> <div class="sl-link-card astro-lyux3snc"> <span class="sl-flex stack astro-lyux3snc"> <a href="/agents/concepts/agentic-patterns/human-in-the-loop/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Human-in-the-loop</span> </a> <span class="description astro-lyux3snc">Deeper patterns for approval flows and manual intervention.</span> </span> <svg aria-hidden="true" class="icon rtl:flip astro-lyux3snc astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.333em;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg> </div> </div> <footer class="sl-flex astro-fxeopwe4"> <div class="custom-footer-section w-full astro-fxeopwe4"> <div class="grid grid-cols-2 gap-8 pt-6 pb-10 lg:grid-cols-5 astro-fxeopwe4"> <ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Resources</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="/api/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> API </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/fundamentals/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> New to Cloudflare? </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/directory/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Directory </a> </li><li class="text-sm astro-fxeopwe4"> <a href="/sponsorships/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Sponsorships </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://github.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Open Source </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://research.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Research </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Support</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://support.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Help Center </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflarestatus.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> System Status </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/trust-hub/compliance-resources/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Compliance </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/trust-hub/gdpr/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> GDPR </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Company</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> cloudflare.com </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/people/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Our team </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.cloudflare.com/careers/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Careers </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Tools</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://radar.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Radar </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://labs.cloudflare.dev/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Cloudflare Labs </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://speed.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Speed Test </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://isbgpsafeyet.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Is BGP Safe Yet? </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://ct.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> Certificate Transparency </a> </li> </ul><ul class="flex w-full list-none flex-col gap-3 pl-0 astro-fxeopwe4"> <li class="text-xs leading-5 astro-fxeopwe4"> <strong class="astro-fxeopwe4">Community</strong> </li> <li class="text-sm astro-fxeopwe4"> <a href="https://community.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M16.5 16.84c.16-.5.1-.97-.15-1.3-.22-.33-.6-.5-1.06-.53l-8.66-.11a.15.15 0 0 1-.13-.08.21.21 0 0 1-.02-.15.25.25 0 0 1 .2-.15l8.74-.12a3.13 3.13 0 0 0 2.55-1.91l.5-1.3a.25.25 0 0 0 .01-.17 5.68 5.68 0 0 0-10.93-.59 2.58 2.58 0 0 0-3.35.24 2.55 2.55 0 0 0-.67 2.44 3.64 3.64 0 0 0-3.5 4.17.18.18 0 0 0 .17.15h15.98a.22.22 0 0 0 .21-.16l.12-.43Zm2.77-5.56-.24.01c-.06 0-.1.05-.13.1l-.34 1.18c-.15.5-.1.97.16 1.31.22.32.6.5 1.06.52l1.84.12c.06 0 .1.02.14.07.02.04.03.1.02.15a.23.23 0 0 1-.2.15l-1.93.12a3.11 3.11 0 0 0-2.55 1.91l-.14.36c-.03.07.02.14.1.14h6.6a.18.18 0 0 0 .16-.12 4.74 4.74 0 0 0-4.56-6v-.02Z"/></svg> Community forum </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://x.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M 18.242188 2.25 L 21.554688 2.25 L 14.324219 10.507812 L 22.828125 21.75 L 16.171875 21.75 L 10.953125 14.933594 L 4.992188 21.75 L 1.679688 21.75 L 9.40625 12.914062 L 1.257812 2.25 L 8.082031 2.25 L 12.792969 8.480469 Z M 17.082031 19.773438 L 18.914062 19.773438 L 7.082031 4.125 L 5.113281 4.125 Z M 17.082031 19.773438 "/></svg> X </a> </li><li class="text-sm astro-fxeopwe4"> <a href="http://discord.cloudflare.com/" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M20.32 4.37a19.8 19.8 0 0 0-4.93-1.51 13.78 13.78 0 0 0-.64 1.28 18.27 18.27 0 0 0-5.5 0 12.64 12.64 0 0 0-.64-1.28h-.05A19.74 19.74 0 0 0 3.64 4.4 20.26 20.26 0 0 0 .11 18.09l.02.02a19.9 19.9 0 0 0 6.04 3.03l.04-.02a14.24 14.24 0 0 0 1.23-2.03.08.08 0 0 0-.05-.07 13.1 13.1 0 0 1-1.9-.92.08.08 0 0 1 .02-.1 10.2 10.2 0 0 0 .41-.31h.04a14.2 14.2 0 0 0 12.1 0l.04.01a9.63 9.63 0 0 0 .4.32.08.08 0 0 1-.03.1 12.29 12.29 0 0 1-1.9.91.08.08 0 0 0-.02.1 15.97 15.97 0 0 0 1.27 2.01h.04a19.84 19.84 0 0 0 6.03-3.05v-.03a20.12 20.12 0 0 0-3.57-13.69ZM8.02 15.33c-1.18 0-2.16-1.08-2.16-2.42 0-1.33.96-2.42 2.16-2.42 1.21 0 2.18 1.1 2.16 2.42 0 1.34-.96 2.42-2.16 2.42Zm7.97 0c-1.18 0-2.15-1.08-2.15-2.42 0-1.33.95-2.42 2.15-2.42 1.22 0 2.18 1.1 2.16 2.42 0 1.34-.94 2.42-2.16 2.42Z"/></svg> Discord </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://www.youtube.com/cloudflare" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M23.5 6.2A3 3 0 0 0 21.4 4c-1.9-.5-9.4-.5-9.4-.5s-7.5 0-9.4.5A3 3 0 0 0 .5 6.3C0 8 0 12 0 12s0 4 .5 5.8A3 3 0 0 0 2.6 20c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2c.5-2 .5-5.9.5-5.9s0-4-.5-5.8zm-14 9.4V8.4l6.3 3.6-6.3 3.6z"/></svg> YouTube </a> </li><li class="text-sm astro-fxeopwe4"> <a href="https://github.com/cloudflare/cloudflare-docs" class="flex items-center gap-2 text-black! no-underline astro-fxeopwe4"> <svg aria-hidden="true" class="astro-fxeopwe4 astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1em;"><path d="M12 .3a12 12 0 0 0-3.8 23.38c.6.12.83-.26.83-.57L9 21.07c-3.34.72-4.04-1.61-4.04-1.61-.55-1.39-1.34-1.76-1.34-1.76-1.08-.74.09-.73.09-.73 1.2.09 1.83 1.24 1.83 1.24 1.08 1.83 2.81 1.3 3.5 1 .1-.78.42-1.31.76-1.61-2.67-.3-5.47-1.33-5.47-5.93 0-1.31.47-2.38 1.24-3.22-.14-.3-.54-1.52.1-3.18 0 0 1-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.28-1.55 3.29-1.23 3.29-1.23.64 1.66.24 2.88.12 3.18a4.65 4.65 0 0 1 1.23 3.22c0 4.61-2.8 5.63-5.48 5.92.42.36.81 1.1.81 2.22l-.01 3.29c0 .31.2.69.82.57A12 12 0 0 0 12 .3Z"/></svg> GitHub </a> </li> </ul> </div> <div class="astro-fxeopwe4"> <ul class="text-cl1-gray-4! dark:text-cl1-gray-7! flex list-inside flex-wrap items-center justify-center gap-3 gap-y-4 pl-0 text-xs astro-fxeopwe4"> <li class="list-none astro-fxeopwe4">© 2026 Cloudflare, Inc.</li> <li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/privacypolicy/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Privacy Policy </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/website-terms/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Terms of Use </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/disclosure/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Report Security Issues </a> </li><li class="astro-fxeopwe4"> <a href="https://www.cloudflare.com/trademark/" class="text-cl1-gray-4! dark:text-cl1-gray-7! no-underline astro-fxeopwe4"> Trademark </a> </li> <li class="astro-fxeopwe4"> <script src="https://ot.www.cloudflare.com/public/vendor/onetrust/scripttemplates/otSDKStub.js" type="text/javascript" charset="UTF-8" data-domain-script="b1e05d49-f072-4bae-9116-bdb78af15448"></script> <script type="text/javascript"> // eslint-disable-next-line @typescript-eslint/no-unused-vars function OptanonWrapper() {} </script> <!-- OneTrust Cookies Settings button start --><div class="inline-flex items-center gap-2 astro-hwxmvrii"> <img src="/_astro/privacyoptions.BWXSiJOZ_1zBYaH.svg" alt="privacy options" loading="lazy" decoding="async" width="26" height="12" class="astro-hwxmvrii"> <button id="ot-sdk-btn" class="ot-sdk-show-settings astro-hwxmvrii">Cookie Settings</button> </div> <!-- OneTrust Cookies Settings button end --> </li> </ul> </div> </div> <div class="starlight-footer-section astro-fxeopwe4"> <div class="pagination-links print:hidden astro-zujpvvea" dir="ltr"> <a href="/agents/runtime/operations/observability/" rel="prev" class="astro-zujpvvea"> <svg aria-hidden="true" class="astro-zujpvvea astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17 11H9.41l3.3-3.29a1.004 1.004 0 1 0-1.42-1.42l-5 5a1 1 0 0 0-.21.33 1 1 0 0 0 0 .76 1 1 0 0 0 .21.33l5 5a1.002 1.002 0 0 0 1.639-.325 1 1 0 0 0-.219-1.095L9.41 13H17a1 1 0 0 0 0-2Z"/></svg> <span class="astro-zujpvvea"> Previous <br class="astro-zujpvvea"> <span class="link-title astro-zujpvvea">Observability</span> </span> </a> <a href="/agents/examples/slack-agent/" rel="next" class="astro-zujpvvea"> <svg aria-hidden="true" class="astro-zujpvvea astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.5rem;"><path d="M17.92 11.62a1.001 1.001 0 0 0-.21-.33l-5-5a1.003 1.003 0 1 0-1.42 1.42l3.3 3.29H7a1 1 0 0 0 0 2h7.59l-3.3 3.29a1.002 1.002 0 0 0 .325 1.639 1 1 0 0 0 1.095-.219l5-5a1 1 0 0 0 .21-.33 1 1 0 0 0 0-.76Z"/></svg> <span class="astro-zujpvvea"> Next <br class="astro-zujpvvea"> <span class="link-title astro-zujpvvea">Slack agent</span> </span> </a> </div> <div class="meta sl-flex astro-fxeopwe4"> <a href="https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/agents/examples/chat-agent.mdx" class="sl-flex print:hidden astro-cdtc2x7r"><svg aria-hidden="true" class="astro-cdtc2x7r astro-r7kprdcr" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" style="--sl-icon-size: 1.2em;"><path d="M22 7.24a1 1 0 0 0-.29-.71l-4.24-4.24a1 1 0 0 0-1.1-.22 1 1 0 0 0-.32.22l-2.83 2.83L2.29 16.05a1 1 0 0 0-.29.71V21a1 1 0 0 0 1 1h4.24a1 1 0 0 0 .76-.29l10.87-10.93L21.71 8c.1-.1.17-.2.22-.33a1 1 0 0 0 0-.24v-.14l.07-.05ZM6.83 20H4v-2.83l9.93-9.93 2.83 2.83L6.83 20ZM18.17 8.66l-2.83-2.83 1.42-1.41 2.82 2.82-1.41 1.42Z"/></svg>Edit page</a> <p>Last updated: <time datetime="2026-06-09T19:55:54.000Z">Jun 9, 2026</time></p> </div> </div> <div class="feedback-prompt astro-fxeopwe4"> <astro-island uid="1gAukP" prefix="r3" component-url="/_astro/FeedbackPrompt.FVI-KaJz.js" component-export="default" renderer-url="/_astro/client.hmfmp3Nb.js" props="{}" ssr client="idle" opts="{&quot;name&quot;:&quot;FeedbackPrompt&quot;,&quot;value&quot;:true}" await-children><div id="feedback-form"><p class="m-0 text-[11px] font-semibold tracking-widest text-[var(--sl-color-gray-3)] uppercase">Was this helpful?</p><div class="mt-3 flex gap-2"><button class="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border-0 bg-[var(--sl-color-bg-nav)] px-3 text-[13px] font-medium text-[var(--sl-color-text)] shadow-none ring-1 ring-[var(--sl-color-hairline)] transition-colors duration-150 hover:bg-[var(--color-cl1-gray-9)] hover:ring-[var(--sl-color-gray-3)] dark:hover:bg-[var(--color-cl1-gray-2)]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="opacity-70" height="18" width="18" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0zm0 0h24v24H0V0z"></path><path d="M9 21h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.58 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2zM9 9l4.34-4.34L12 10h9v2l-3 7H9V9zM1 9h4v12H1z"></path></svg><span>Yes</span></button><button class="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-lg border-0 bg-[var(--sl-color-bg-nav)] px-3 text-[13px] font-medium text-[var(--sl-color-text)] shadow-none ring-1 ring-[var(--sl-color-hairline)] transition-colors duration-150 hover:bg-[var(--color-cl1-gray-9)] hover:ring-[var(--sl-color-gray-3)] dark:hover:bg-[var(--color-cl1-gray-2)]"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" class="opacity-70" height="18" width="18" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0zm0 0h24v24H0V0z"></path><path d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v2c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm0 12-4.34 4.34L12 14H3v-2l3-7h9v10zm4-12h4v12h-4z"></path></svg><span>No</span></button></div></div><!--astro:end--></astro-island> </div> </footer> </div> </div> </main> </div> </div> </div> </div> </body></html>

Lưu ý trước khi làm Notes before you start

  • Đây là bản tóm tắt trên Orange Cloud Learning Hub — không thay thế tài liệu chính thức. This is a summary on Orange Cloud Learning Hub — it does not replace the official documentation.
  • Luôn mở liên kết «Tài liệu gốc» bên dưới khi cần lệnh CLI, snippet code và ảnh minh họa đầy đủ. Open the Official docs link below for CLI commands, code snippets, and full screenshots.
  • Docs Cloudflare cập nhật thường xuyên — đối chiếu ngày «Rà soát lần cuối» trên trang gốc khi triển khai production. Cloudflare docs change frequently — verify the Last reviewed date on the official page before production use.

Nội dung chi tiết chưa được đồng bộ — mở tài liệu gốc hoặc chạy lại resources:crawl-previews. Detailed content not synced yet — open the official doc or re-run resources:crawl-previews.

Xem bản đầy đủ trên developers.cloudflare.com (ảnh, tab cấu hình). View the full guide on developers.cloudflare.com (images, config tabs).

Tài liệu gốc ↗ Official docs ↗