Tutorial Tutorial Tutorial Chung / đa lĩnh vực Cross-cutting ឆ្លងកាត់ / ពហុវិស័យ ~10 phút ~10 min ~10 នាទី Đồng bộ 2026-06-10 Synced 2026-06-10 ធ្វើសមកាល 2026-06-10

Xây dựng Voice Agent Build a voice 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. មគ្គុទ្ទេសក៍លម្អិតធ្វើសមកាលពី docs Cloudflare — ផ្នែកនីមួយៗមានតំណទៅទីតាំងត្រូវគ្នានៅទំព័រផ្លូវការ។

← 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 voice 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>Voice agent · Cloudflare Agents docs</title><link rel="canonical" href="https://developers.cloudflare.com/agents/examples/voice-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="Voice agent"/><meta property="og:type" content="article"/><meta property="og:url" content="https://developers.cloudflare.com/agents/examples/voice-agent/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Build a real-time voice agent with speech-to-text, LLM processing, and text-to-speech on Cloudflare Workers."/><meta property="og:site_name" content="Cloudflare Docs"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Build a real-time voice agent with speech-to-text, LLM processing, and text-to-speech on Cloudflare Workers."/><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/voice-agent/index.md"/><meta property="og:title" content="Voice 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="Workers,Agents"/><meta name="pcx_last_modified" content="7"/><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/voice-agent/index.md (append index.md) or send Accept: text/markdown to https://developers.cloudflare.com/agents/examples/voice-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/" 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 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/" 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">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="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</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-build-the-server" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Build the server</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-build-the-client" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Build the client</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-run-it" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Run it</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#adding-pipeline-hooks" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Adding pipeline hooks</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#using-third-party-providers" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Using third-party providers</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="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</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-build-the-server" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Build the server</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-build-the-client" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Build the client</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-run-it" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Run it</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#adding-pipeline-hooks" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Adding pipeline hooks</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#using-third-party-providers" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Using third-party providers</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/voice-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/voice-agent/" class="c-breadcrumbs__link is-current" aria-current="location"> Voice 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/voice-agent/","name":"Voice 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">Voice 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 voice agent that listens to users, thinks with an LLM, and speaks back — all in real-time over WebSocket. <span class="sl-badge caution small inline astro-p5lt2pqd">Beta</span></p> <p>By the end of this guide you will have:</p> <ul> <li>A server-side voice agent with speech-to-text and text-to-speech</li> <li>An LLM-powered <code dir="auto">onTurn</code> handler that streams responses</li> <li>Tools that the agent can call during conversation</li> <li>A React client with a push-to-talk style UI</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="prerequisites">Prerequisites</h2><a class="anchor-link" href="#prerequisites"><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>A Cloudflare account with <a href="/workers-ai/">Workers AI</a> access</li> <li>Node.js 18+</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> <p>Scaffold a new Workers project with Vite and React, then add the voice dependencies:</p> <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">voice-agent</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">--</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">--template</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">cloudflare/agents-starter</span></div></div><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">voice-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">@cloudflare/voice</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm create cloudflare@latest voice-agent -- --template cloudflare/agents-startercd voice-agentnpm install @cloudflare/voice"><div></div></button></div></figure></div> <p>The starter gives you a working Vite + React + Cloudflare Workers setup. You will replace the server and client code in the following steps.</p> <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>Update <code dir="auto">wrangler.jsonc</code> to include a Workers AI binding and a Durable Object for your voice agent:</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-5306" id="tab-5306" 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-5307" id="tab-5307" 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-5306" aria-labelledby="tab-5306" 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">"voice-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">// 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">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:#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></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">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></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">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></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:#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">"MyVoiceAgent"</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:#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">"MyVoiceAgent"</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></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></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:#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></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">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">"MyVoiceAgent"</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 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;voice-agent&#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;main&#x22;: &#x22;src/server.ts&#x22;, &#x22;ai&#x22;: { &#x22;binding&#x22;: &#x22;AI&#x22; }, &#x22;durable_objects&#x22;: { &#x22;bindings&#x22;: [ { &#x22;name&#x22;: &#x22;MyVoiceAgent&#x22;, &#x22;class_name&#x22;: &#x22;MyVoiceAgent&#x22; } ] }, &#x22;migrations&#x22;: [ { &#x22;tag&#x22;: &#x22;v1&#x22;, &#x22;new_sqlite_classes&#x22;: [&#x22;MyVoiceAgent&#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-5307" aria-labelledby="tab-5307" 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">"voice-agent"</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"><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"> </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">"MyVoiceAgent"</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">"MyVoiceAgent"</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">"MyVoiceAgent"</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;voice-agent&#x22;# Set this to today&#x27;s datecompatibility_date = &#x22;2026-06-10&#x22;compatibility_flags = [ &#x22;nodejs_compat&#x22; ]main = &#x22;src/server.ts&#x22;[ai]binding = &#x22;AI&#x22;[[durable_objects.bindings]]name = &#x22;MyVoiceAgent&#x22;class_name = &#x22;MyVoiceAgent&#x22;[[migrations]]tag = &#x22;v1&#x22;new_sqlite_classes = [ &#x22;MyVoiceAgent&#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> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="3-build-the-server">3. Build the server</h2><a class="anchor-link" href="#3-build-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>Replace <code dir="auto">src/server.ts</code> with the following. The <code dir="auto">withVoice</code> mixin adds the full voice pipeline — STT, sentence chunking, TTS, and conversation persistence — to a standard <code dir="auto">Agent</code> class.</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-5312" id="tab-5312" 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-5313" id="tab-5313" 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-5312" aria-labelledby="tab-5312" 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">Agent</span></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">withVoice</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">WorkersAIFluxSTT</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">WorkersAITTS</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/voice"</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">streamText</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">tool</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">stepCountIs</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">"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">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><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">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">VoiceAgent</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">withVoice</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">Agent</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 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">MyVoiceAgent</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">VoiceAgent</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">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</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/moonshotai/kimi-k2.6"</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 voice assistant. Keep responses concise — you are being spoken aloud."</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></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#EEFFFF;--1:#00268F">context</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:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">m</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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</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">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">content</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><span style="--0:#EE9080;--1:#32008F"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"user"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">transcript</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">]</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 style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">get_current_time</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 date and time."</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:#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:#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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">time</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:#FDDA68;--1:#A84E00">"en-US"</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">hour</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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">minute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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><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:#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">3</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">abortSignal</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">context</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">signal</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:#EEFFFF;--1:#00268F">textStream</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onCallStart</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">connection</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">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">speak</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">connection</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Hi there! How can I help you today?"</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 { Agent, routeAgentRequest } from &#x22;agents&#x22;;import { withVoice, WorkersAIFluxSTT, WorkersAITTS } from &#x22;@cloudflare/voice&#x22;;import { streamText, tool, stepCountIs } from &#x22;ai&#x22;;import { createWorkersAI } from &#x22;workers-ai-provider&#x22;;import { z } from &#x22;zod&#x22;;const VoiceAgent = withVoice(Agent);export class MyVoiceAgent extends VoiceAgent { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); async onTurn(transcript, context) { const workersAi = createWorkersAI({ binding: this.env.AI }); const result = streamText({ model: workersAi(&#x22;@cf/moonshotai/kimi-k2.6&#x22;), system: &#x22;You are a helpful voice assistant. Keep responses concise — you are being spoken aloud.&#x22;, messages: [ ...context.messages.map((m) => ({ role: m.role, content: m.content, })), { role: &#x22;user&#x22;, content: transcript }, ], tools: { get_current_time: tool({ description: &#x22;Get the current date and time.&#x22;, inputSchema: z.object({}), execute: async () => ({ time: new Date().toLocaleTimeString(&#x22;en-US&#x22;, { hour: &#x22;2-digit&#x22;, minute: &#x22;2-digit&#x22;, }), }), }), }, stopWhen: stepCountIs(3), abortSignal: context.signal, }); return result.textStream; } async onCallStart(connection) { await this.speak(connection, &#x22;Hi there! How can I help you today?&#x22;); }}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-5313" aria-labelledby="tab-5313" 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">Agent</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">routeAgentRequest</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> type </span><span style="--0:#D5D7D8">Connection</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></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">withVoice</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">WorkersAIFluxSTT</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">WorkersAITTS</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:#8F1500"> </span></span><span style="--0:#EE9080;--1:#8F1500">type </span><span style="--0:#D5D7D8;--1:#8F1500">VoiceTurnContext</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">"@cloudflare/voice"</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">streamText</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">tool</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">stepCountIs</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">"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">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><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">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">VoiceAgent</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">withVoice</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">Agent</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 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">MyVoiceAgent</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">VoiceAgent</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</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 style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">VoiceTurnContext</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/moonshotai/kimi-k2.6"</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 voice assistant. Keep responses concise — you are being spoken aloud."</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></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#EEFFFF;--1:#00268F">context</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:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">m</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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</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:#FDDA68;--1:#A84E00">"user"</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">"assistant"</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">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">content</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><span style="--0:#EE9080;--1:#32008F"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"user"</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:#EE9080;--1:#8F1500">const</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">transcript</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">]</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 style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">get_current_time</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 date and time."</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:#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:#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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">time</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:#FDDA68;--1:#A84E00">"en-US"</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">hour</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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">minute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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><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:#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">3</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">abortSignal</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">context</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">signal</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:#EEFFFF;--1:#00268F">textStream</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onCallStart</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">connection</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Connection</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">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">speak</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">connection</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Hi there! How can I help you today?"</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 { Agent, routeAgentRequest, type Connection } from &#x22;agents&#x22;;import { withVoice, WorkersAIFluxSTT, WorkersAITTS, type VoiceTurnContext,} from &#x22;@cloudflare/voice&#x22;;import { streamText, tool, stepCountIs } from &#x22;ai&#x22;;import { createWorkersAI } from &#x22;workers-ai-provider&#x22;;import { z } from &#x22;zod&#x22;;const VoiceAgent = withVoice(Agent);export class MyVoiceAgent extends VoiceAgent<Env> { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); async onTurn(transcript: string, context: VoiceTurnContext) { const workersAi = createWorkersAI({ binding: this.env.AI }); const result = streamText({ model: workersAi(&#x22;@cf/moonshotai/kimi-k2.6&#x22;), system: &#x22;You are a helpful voice assistant. Keep responses concise — you are being spoken aloud.&#x22;, messages: [ ...context.messages.map((m) => ({ role: m.role as &#x22;user&#x22; | &#x22;assistant&#x22;, content: m.content, })), { role: &#x22;user&#x22; as const, content: transcript }, ], tools: { get_current_time: tool({ description: &#x22;Get the current date and time.&#x22;, inputSchema: z.object({}), execute: async () => ({ time: new Date().toLocaleTimeString(&#x22;en-US&#x22;, { hour: &#x22;2-digit&#x22;, minute: &#x22;2-digit&#x22;, }), }), }), }, stopWhen: stepCountIs(3), abortSignal: context.signal, }); return result.textStream; } async onCallStart(connection: Connection) { await this.speak(connection, &#x22;Hi there! How can I help you today?&#x22;); }}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> <p>Key points:</p> <ul> <li><code dir="auto">WorkersAIFluxSTT</code> handles continuous speech-to-text — the model detects when the user finishes speaking.</li> <li><code dir="auto">WorkersAITTS</code> converts the LLM response to audio, sentence by sentence.</li> <li><code dir="auto">onTurn</code> receives the transcript and returns a stream. The mixin handles chunking the stream into sentences and synthesizing each one.</li> <li><code dir="auto">onCallStart</code> sends a greeting when the user connects.</li> <li><code dir="auto">context.messages</code> contains the full conversation history from SQLite.</li> <li><code dir="auto">context.signal</code> is aborted if the user interrupts or disconnects.</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="4-build-the-client">4. Build the client</h2><a class="anchor-link" href="#4-build-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>Replace <code dir="auto">src/client.tsx</code> with a React component using the <code dir="auto">useVoiceAgent</code> hook. The hook manages the WebSocket connection, mic capture, audio playback, and interrupt detection.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="tsx"><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">useVoiceAgent</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/voice/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">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">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">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:#EEFFFF;--1:#00268F">transcript</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">interimTranscript</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">metrics</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">audioLevel</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">isMuted</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">startCall</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">endCall</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">toggleMute</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">useVoiceAgent</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">"MyVoiceAgent"</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">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">h1</span><span style="--0:#89DDFF;--1:#007474">>Voice Agent&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">h1</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">>Status: {</span><span style="--0:#D5D7D8;--1:#8F1500">status</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"> </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">&#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">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">"idle"</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:#D5D7D8;--1:#8F1500">startCall</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:#D5D7D8;--1:#8F1500">endCall</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:#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">"idle"</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">"Start Call"</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">"End Call"</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></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:#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">"idle"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</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">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">toggleMute</span><span style="--0:#89DDFF;--1:#007474">}>{</span><span style="--0:#D5D7D8;--1:#8F1500">isMuted</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">"Unmute"</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">"Mute"</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">)}</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">{</span><span style="--0:#D5D7D8;--1:#8F1500">interimTranscript</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</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">em</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#D5D7D8;--1:#8F1500">interimTranscript</span><span style="--0:#89DDFF;--1:#007474">}&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">em</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">)}</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">{</span><span style="--0:#EEFFFF;--1:#00268F">transcript</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:#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 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><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></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><span style="--0:#EEFFFF;--1:#00268F">msg</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">text</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">))}</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">{</span><span style="--0:#D5D7D8;--1:#8F1500">metrics</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</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">LLM: {</span><span style="--0:#EEFFFF;--1:#00268F">metrics</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">llm_ms</span><span style="--0:#89DDFF;--1:#007474">}ms | TTS: {</span><span style="--0:#EEFFFF;--1:#00268F">metrics</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">tts_ms</span><span style="--0:#89DDFF;--1:#007474">}ms | First audio:{</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><span style="--0:#EEFFFF;--1:#00268F">metrics</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">first_audio_ms</span><span style="--0:#89DDFF;--1:#007474">}ms</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">)}</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></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { useVoiceAgent } from &#x22;@cloudflare/voice/react&#x22;;function App() { const { status, transcript, interimTranscript, metrics, audioLevel, isMuted, startCall, endCall, toggleMute, } = useVoiceAgent({ agent: &#x22;MyVoiceAgent&#x22; }); return ( <div> <h1>Voice Agent</h1> <p>Status: {status}</p> <div> <button onClick={status === &#x22;idle&#x22; ? startCall : endCall}> {status === &#x22;idle&#x22; ? &#x22;Start Call&#x22; : &#x22;End Call&#x22;} </button> {status !== &#x22;idle&#x22; &#x26;&#x26; ( <button onClick={toggleMute}>{isMuted ? &#x22;Unmute&#x22; : &#x22;Mute&#x22;}</button> )} </div> {interimTranscript &#x26;&#x26; ( <p> <em>{interimTranscript}</em> </p> )} {transcript.map((msg, i) => ( <p key={i}> <strong>{msg.role}:</strong> {msg.text} </p> ))} {metrics &#x26;&#x26; ( <p> LLM: {metrics.llm_ms}ms | TTS: {metrics.tts_ms}ms | First audio:{&#x22; &#x22;} {metrics.first_audio_ms}ms </p> )} </div> );}"><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> <p>The <code dir="auto">status</code> field cycles through <code dir="auto">"idle"</code> → <code dir="auto">"listening"</code> → <code dir="auto">"thinking"</code> → <code dir="auto">"speaking"</code> → <code dir="auto">"listening"</code>, giving you everything you need to build a responsive UI.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="5-run-it">5. Run it</h2><a class="anchor-link" href="#5-run-it"><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">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="npm run dev"><div></div></button></div></figure></div> <p>Open the app in your browser, select <strong>Start Call</strong>, and speak. You will see the transcript appear in real time, and the agent's response will play through your speakers.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="adding-pipeline-hooks">Adding pipeline hooks</h2><a class="anchor-link" href="#adding-pipeline-hooks"><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>You can intercept and transform data at each stage of the pipeline. For example, filter out short transcripts (noise) and adjust pronunciation before TTS:</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-5308" id="tab-5308" 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-5309" id="tab-5309" 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-5308" aria-labelledby="tab-5308" 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">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">MyVoiceAgent</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">VoiceAgent</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">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#57C78F;--1:#00783C">afterTranscribe</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</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">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">transcript</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&#x3C;</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">3</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><span style="--0:#D5D7D8;--1:#8F1500">transcript</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:#57C78F;--1:#00783C">beforeSynthesize</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">text</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</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:#EEFFFF;--1:#00268F">text</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">replace</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#89DDFF;--1:#446E7F">AI</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#8EA7ED;--1:#00268F">g</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"A.I."</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"> </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">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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="export class MyVoiceAgent extends VoiceAgent { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); afterTranscribe(transcript, connection) { if (transcript.length < 3) return null; return transcript; } beforeSynthesize(text, connection) { return text.replace(/\bAI\b/g, &#x22;A.I.&#x22;); } async onTurn(transcript, context) { return &#x22;You said: &#x22; + transcript; }}"><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-5309" aria-labelledby="tab-5309" 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">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">MyVoiceAgent</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">VoiceAgent</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</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 style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#57C78F;--1:#00783C">afterTranscribe</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Connection</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">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">transcript</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&#x3C;</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">3</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><span style="--0:#D5D7D8;--1:#8F1500">transcript</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:#57C78F;--1:#00783C">beforeSynthesize</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">text</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Connection</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:#EEFFFF;--1:#00268F">text</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">replace</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#89DDFF;--1:#446E7F">AI</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#8EA7ED;--1:#00268F">g</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"A.I."</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"> </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">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">VoiceTurnContext</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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="export class MyVoiceAgent extends VoiceAgent<Env> { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); afterTranscribe(transcript: string, connection: Connection) { if (transcript.length < 3) return null; return transcript; } beforeSynthesize(text: string, connection: Connection) { return text.replace(/\bAI\b/g, &#x22;A.I.&#x22;); } async onTurn(transcript: string, context: VoiceTurnContext) { return &#x22;You said: &#x22; + transcript; }}"><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> <p>Returning <code dir="auto">null</code> from <code dir="auto">afterTranscribe</code> drops the utterance entirely — useful for filtering noise or very short transcripts.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="using-third-party-providers">Using third-party providers</h2><a class="anchor-link" href="#using-third-party-providers"><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>Swap in third-party STT or TTS providers without changing your agent logic:</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-5310" id="tab-5310" 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-5311" id="tab-5311" 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-5310" aria-labelledby="tab-5310" 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">ElevenLabsTTS</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/voice-elevenlabs"</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">DeepgramSTT</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/voice-deepgram"</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">MyVoiceAgent</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">VoiceAgent</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">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">DeepgramSTT</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">DEEPGRAM_API_KEY</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:#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 class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ElevenLabsTTS</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">ELEVENLABS_API_KEY</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">voiceId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"21m00Tcm4TlvDq8ikWAM"</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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 { ElevenLabsTTS } from &#x22;@cloudflare/voice-elevenlabs&#x22;;import { DeepgramSTT } from &#x22;@cloudflare/voice-deepgram&#x22;;export class MyVoiceAgent extends VoiceAgent { transcriber = new DeepgramSTT({ apiKey: this.env.DEEPGRAM_API_KEY, }); tts = new ElevenLabsTTS({ apiKey: this.env.ELEVENLABS_API_KEY, voiceId: &#x22;21m00Tcm4TlvDq8ikWAM&#x22;, }); async onTurn(transcript, context) { return &#x22;You said: &#x22; + transcript; }}"><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-5311" aria-labelledby="tab-5311" 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">ElevenLabsTTS</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/voice-elevenlabs"</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">DeepgramSTT</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/voice-deepgram"</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">MyVoiceAgent</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">VoiceAgent</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</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 style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">DeepgramSTT</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">DEEPGRAM_API_KEY</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:#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 class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ElevenLabsTTS</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">ELEVENLABS_API_KEY</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">voiceId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"21m00Tcm4TlvDq8ikWAM"</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">VoiceTurnContext</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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 { ElevenLabsTTS } from &#x22;@cloudflare/voice-elevenlabs&#x22;;import { DeepgramSTT } from &#x22;@cloudflare/voice-deepgram&#x22;;export class MyVoiceAgent extends VoiceAgent<Env> { transcriber = new DeepgramSTT({ apiKey: this.env.DEEPGRAM_API_KEY, }); tts = new ElevenLabsTTS({ apiKey: this.env.ELEVENLABS_API_KEY, voiceId: &#x22;21m00Tcm4TlvDq8ikWAM&#x22;, }); async onTurn(transcript: string, context: VoiceTurnContext) { return &#x22;You said: &#x22; + transcript; }}"><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-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/voice/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Voice agents API reference</span> </a> <span class="description astro-lyux3snc">Full reference for withVoice, withVoiceInput, React hooks, VoiceClient, and all providers.</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/communication-channels/chat/chat-agents/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Chat agents</span> </a> <span class="description astro-lyux3snc">Build text-based AI chat with AIChatAgent and useAgentChat.</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/operations/using-ai-models/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Using AI models</span> </a> <span class="description astro-lyux3snc">Use Workers AI, OpenAI, Anthropic, Gemini, or any provider with your agents.</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/examples/slack-agent/" 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">Slack agent</span> </span> </a> <a href="/agents/examples/browser-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">Browser 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/voice-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-03T15:55:00.000Z">Jun 3, 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>

<!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>Voice agent · Cloudflare Agents docs</title><link rel="canonical" href="https://developers.cloudflare.com/agents/examples/voice-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="Voice agent"/><meta property="og:type" content="article"/><meta property="og:url" content="https://developers.cloudflare.com/agents/examples/voice-agent/"/><meta property="og:locale" content="en"/><meta property="og:description" content="Build a real-time voice agent with speech-to-text, LLM processing, and text-to-speech on Cloudflare Workers."/><meta property="og:site_name" content="Cloudflare Docs"/><meta name="twitter:card" content="summary_large_image"/><meta name="description" content="Build a real-time voice agent with speech-to-text, LLM processing, and text-to-speech on Cloudflare Workers."/><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/voice-agent/index.md"/><meta property="og:title" content="Voice 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="Workers,Agents"/><meta name="pcx_last_modified" content="7"/><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/voice-agent/index.md (append index.md) or send Accept: text/markdown to https://developers.cloudflare.com/agents/examples/voice-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/" 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 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/" 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">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="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</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-build-the-server" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Build the server</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-build-the-client" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Build the client</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-run-it" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Run it</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#adding-pipeline-hooks" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Adding pipeline hooks</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#using-third-party-providers" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Using third-party providers</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="#prerequisites" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Prerequisites</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-build-the-server" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">3. Build the server</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#4-build-the-client" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">4. Build the client</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#5-run-it" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">5. Run it</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#adding-pipeline-hooks" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Adding pipeline hooks</span> </a> </li><li class="astro-n5w67532" style="--depth: 0;"> <a href="#using-third-party-providers" class="astro-n5w67532" style="--depth: 0;"> <span class="astro-n5w67532" style="--depth: 0;">Using third-party providers</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/voice-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/voice-agent/" class="c-breadcrumbs__link is-current" aria-current="location"> Voice 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/voice-agent/","name":"Voice 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">Voice 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 voice agent that listens to users, thinks with an LLM, and speaks back — all in real-time over WebSocket. <span class="sl-badge caution small inline astro-p5lt2pqd">Beta</span></p> <p>By the end of this guide you will have:</p> <ul> <li>A server-side voice agent with speech-to-text and text-to-speech</li> <li>An LLM-powered <code dir="auto">onTurn</code> handler that streams responses</li> <li>Tools that the agent can call during conversation</li> <li>A React client with a push-to-talk style UI</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="prerequisites">Prerequisites</h2><a class="anchor-link" href="#prerequisites"><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>A Cloudflare account with <a href="/workers-ai/">Workers AI</a> access</li> <li>Node.js 18+</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> <p>Scaffold a new Workers project with Vite and React, then add the voice dependencies:</p> <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">voice-agent</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">--</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">--template</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">cloudflare/agents-starter</span></div></div><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">voice-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">@cloudflare/voice</span></div></div></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="npm create cloudflare@latest voice-agent -- --template cloudflare/agents-startercd voice-agentnpm install @cloudflare/voice"><div></div></button></div></figure></div> <p>The starter gives you a working Vite + React + Cloudflare Workers setup. You will replace the server and client code in the following steps.</p> <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>Update <code dir="auto">wrangler.jsonc</code> to include a Workers AI binding and a Durable Object for your voice agent:</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-5306" id="tab-5306" 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-5307" id="tab-5307" 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-5306" aria-labelledby="tab-5306" 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">"voice-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">// 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">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:#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></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">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></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">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></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:#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">"MyVoiceAgent"</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:#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">"MyVoiceAgent"</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></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></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:#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></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">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">"MyVoiceAgent"</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 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;voice-agent&#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;main&#x22;: &#x22;src/server.ts&#x22;, &#x22;ai&#x22;: { &#x22;binding&#x22;: &#x22;AI&#x22; }, &#x22;durable_objects&#x22;: { &#x22;bindings&#x22;: [ { &#x22;name&#x22;: &#x22;MyVoiceAgent&#x22;, &#x22;class_name&#x22;: &#x22;MyVoiceAgent&#x22; } ] }, &#x22;migrations&#x22;: [ { &#x22;tag&#x22;: &#x22;v1&#x22;, &#x22;new_sqlite_classes&#x22;: [&#x22;MyVoiceAgent&#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-5307" aria-labelledby="tab-5307" 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">"voice-agent"</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"><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"> </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">"MyVoiceAgent"</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">"MyVoiceAgent"</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">"MyVoiceAgent"</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;voice-agent&#x22;# Set this to today&#x27;s datecompatibility_date = &#x22;2026-06-10&#x22;compatibility_flags = [ &#x22;nodejs_compat&#x22; ]main = &#x22;src/server.ts&#x22;[ai]binding = &#x22;AI&#x22;[[durable_objects.bindings]]name = &#x22;MyVoiceAgent&#x22;class_name = &#x22;MyVoiceAgent&#x22;[[migrations]]tag = &#x22;v1&#x22;new_sqlite_classes = [ &#x22;MyVoiceAgent&#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> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="3-build-the-server">3. Build the server</h2><a class="anchor-link" href="#3-build-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>Replace <code dir="auto">src/server.ts</code> with the following. The <code dir="auto">withVoice</code> mixin adds the full voice pipeline — STT, sentence chunking, TTS, and conversation persistence — to a standard <code dir="auto">Agent</code> class.</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-5312" id="tab-5312" 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-5313" id="tab-5313" 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-5312" aria-labelledby="tab-5312" 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">Agent</span></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">withVoice</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">WorkersAIFluxSTT</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">WorkersAITTS</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/voice"</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">streamText</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">tool</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">stepCountIs</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">"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">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><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">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">VoiceAgent</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">withVoice</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">Agent</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 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">MyVoiceAgent</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">VoiceAgent</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">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</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/moonshotai/kimi-k2.6"</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 voice assistant. Keep responses concise — you are being spoken aloud."</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></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#EEFFFF;--1:#00268F">context</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:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">m</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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</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">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">content</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><span style="--0:#EE9080;--1:#32008F"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"user"</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">transcript</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">]</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 style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">get_current_time</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 date and time."</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:#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:#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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">time</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:#FDDA68;--1:#A84E00">"en-US"</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">hour</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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">minute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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><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:#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">3</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">abortSignal</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">context</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">signal</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:#EEFFFF;--1:#00268F">textStream</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onCallStart</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">connection</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">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">speak</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">connection</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Hi there! How can I help you today?"</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 { Agent, routeAgentRequest } from &#x22;agents&#x22;;import { withVoice, WorkersAIFluxSTT, WorkersAITTS } from &#x22;@cloudflare/voice&#x22;;import { streamText, tool, stepCountIs } from &#x22;ai&#x22;;import { createWorkersAI } from &#x22;workers-ai-provider&#x22;;import { z } from &#x22;zod&#x22;;const VoiceAgent = withVoice(Agent);export class MyVoiceAgent extends VoiceAgent { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); async onTurn(transcript, context) { const workersAi = createWorkersAI({ binding: this.env.AI }); const result = streamText({ model: workersAi(&#x22;@cf/moonshotai/kimi-k2.6&#x22;), system: &#x22;You are a helpful voice assistant. Keep responses concise — you are being spoken aloud.&#x22;, messages: [ ...context.messages.map((m) => ({ role: m.role, content: m.content, })), { role: &#x22;user&#x22;, content: transcript }, ], tools: { get_current_time: tool({ description: &#x22;Get the current date and time.&#x22;, inputSchema: z.object({}), execute: async () => ({ time: new Date().toLocaleTimeString(&#x22;en-US&#x22;, { hour: &#x22;2-digit&#x22;, minute: &#x22;2-digit&#x22;, }), }), }), }, stopWhen: stepCountIs(3), abortSignal: context.signal, }); return result.textStream; } async onCallStart(connection) { await this.speak(connection, &#x22;Hi there! How can I help you today?&#x22;); }}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-5313" aria-labelledby="tab-5313" 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">Agent</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">routeAgentRequest</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> type </span><span style="--0:#D5D7D8">Connection</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></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--1:#8F1500"> </span></span><span style="--0:#D5D7D8;--1:#8F1500">withVoice</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">WorkersAIFluxSTT</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">WorkersAITTS</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:#8F1500"> </span></span><span style="--0:#EE9080;--1:#8F1500">type </span><span style="--0:#D5D7D8;--1:#8F1500">VoiceTurnContext</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">"@cloudflare/voice"</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">streamText</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">tool</span></span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--1:#8F1500"><span style="--0:#EE9080"> </span><span style="--0:#D5D7D8">stepCountIs</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">"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">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><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">const</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">VoiceAgent</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">withVoice</span><span style="--0:#EE9080;--1:#32008F">(</span><span style="--0:#D5D7D8;--1:#8F1500">Agent</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 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">MyVoiceAgent</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">VoiceAgent</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</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 style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">VoiceTurnContext</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/moonshotai/kimi-k2.6"</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 voice assistant. Keep responses concise — you are being spoken aloud."</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></div></div><div class="ec-line"><div class="code"><span class="indent"><span style="--0:#EE9080"> </span></span><span style="--0:#EE9080;--1:#8F1500">...</span><span style="--0:#EEFFFF;--1:#00268F">context</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:#EE9080;--1:#32008F">(</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">m</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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">role</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:#FDDA68;--1:#A84E00">"user"</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">"assistant"</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">content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">m</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">content</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><span style="--0:#EE9080;--1:#32008F"> role</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"user"</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:#EE9080;--1:#8F1500">const</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EE9080;--1:#32008F"> content</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#D5D7D8;--1:#8F1500">transcript</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">]</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 style="--0:#EE9080;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">get_current_time</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 date and time."</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:#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:#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;--1:#32008F"> </span></span><span style="--0:#EE9080;--1:#32008F">time</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:#FDDA68;--1:#A84E00">"en-US"</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">hour</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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">minute</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#FDDA68;--1:#A84E00">"2-digit"</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><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:#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">3</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">abortSignal</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EE9080;--1:#32008F"> </span><span style="--0:#EEFFFF;--1:#00268F">context</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">signal</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:#EEFFFF;--1:#00268F">textStream</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:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onCallStart</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">connection</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Connection</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">await</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FF8398;--0fs:italic;--1:#B73C51;--1fs:italic">this</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">speak</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#D5D7D8;--1:#8F1500">connection</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"Hi there! How can I help you today?"</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 { Agent, routeAgentRequest, type Connection } from &#x22;agents&#x22;;import { withVoice, WorkersAIFluxSTT, WorkersAITTS, type VoiceTurnContext,} from &#x22;@cloudflare/voice&#x22;;import { streamText, tool, stepCountIs } from &#x22;ai&#x22;;import { createWorkersAI } from &#x22;workers-ai-provider&#x22;;import { z } from &#x22;zod&#x22;;const VoiceAgent = withVoice(Agent);export class MyVoiceAgent extends VoiceAgent<Env> { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); async onTurn(transcript: string, context: VoiceTurnContext) { const workersAi = createWorkersAI({ binding: this.env.AI }); const result = streamText({ model: workersAi(&#x22;@cf/moonshotai/kimi-k2.6&#x22;), system: &#x22;You are a helpful voice assistant. Keep responses concise — you are being spoken aloud.&#x22;, messages: [ ...context.messages.map((m) => ({ role: m.role as &#x22;user&#x22; | &#x22;assistant&#x22;, content: m.content, })), { role: &#x22;user&#x22; as const, content: transcript }, ], tools: { get_current_time: tool({ description: &#x22;Get the current date and time.&#x22;, inputSchema: z.object({}), execute: async () => ({ time: new Date().toLocaleTimeString(&#x22;en-US&#x22;, { hour: &#x22;2-digit&#x22;, minute: &#x22;2-digit&#x22;, }), }), }), }, stopWhen: stepCountIs(3), abortSignal: context.signal, }); return result.textStream; } async onCallStart(connection: Connection) { await this.speak(connection, &#x22;Hi there! How can I help you today?&#x22;); }}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> <p>Key points:</p> <ul> <li><code dir="auto">WorkersAIFluxSTT</code> handles continuous speech-to-text — the model detects when the user finishes speaking.</li> <li><code dir="auto">WorkersAITTS</code> converts the LLM response to audio, sentence by sentence.</li> <li><code dir="auto">onTurn</code> receives the transcript and returns a stream. The mixin handles chunking the stream into sentences and synthesizing each one.</li> <li><code dir="auto">onCallStart</code> sends a greeting when the user connects.</li> <li><code dir="auto">context.messages</code> contains the full conversation history from SQLite.</li> <li><code dir="auto">context.signal</code> is aborted if the user interrupts or disconnects.</li> </ul> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="4-build-the-client">4. Build the client</h2><a class="anchor-link" href="#4-build-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>Replace <code dir="auto">src/client.tsx</code> with a React component using the <code dir="auto">useVoiceAgent</code> hook. The hook manages the WebSocket connection, mic capture, audio playback, and interrupt detection.</p> <div class="expressive-code"><figure class="frame not-content"><figcaption class="header"></figcaption><pre data-language="tsx"><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">useVoiceAgent</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/voice/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">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">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">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:#EEFFFF;--1:#00268F">transcript</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">interimTranscript</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">metrics</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">audioLevel</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">isMuted</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">startCall</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">endCall</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">toggleMute</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">useVoiceAgent</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">"MyVoiceAgent"</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">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">h1</span><span style="--0:#89DDFF;--1:#007474">>Voice Agent&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">h1</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">>Status: {</span><span style="--0:#D5D7D8;--1:#8F1500">status</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"> </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">&#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">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">"idle"</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:#D5D7D8;--1:#8F1500">startCall</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:#D5D7D8;--1:#8F1500">endCall</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:#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">"idle"</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">"Start Call"</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">"End Call"</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></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:#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">"idle"</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</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">onClick</span><span style="--0:#EE9080;--1:#8F1500">=</span><span style="--0:#89DDFF;--1:#007474">{</span><span style="--0:#D5D7D8;--1:#8F1500">toggleMute</span><span style="--0:#89DDFF;--1:#007474">}>{</span><span style="--0:#D5D7D8;--1:#8F1500">isMuted</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">"Unmute"</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">"Mute"</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">)}</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">{</span><span style="--0:#D5D7D8;--1:#8F1500">interimTranscript</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</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">em</span><span style="--0:#89DDFF;--1:#007474">>{</span><span style="--0:#D5D7D8;--1:#8F1500">interimTranscript</span><span style="--0:#89DDFF;--1:#007474">}&#x3C;/</span><span style="--0:#F38B90;--1:#A54E53">em</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">)}</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">{</span><span style="--0:#EEFFFF;--1:#00268F">transcript</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:#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 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><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></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><span style="--0:#EEFFFF;--1:#00268F">msg</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">text</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">))}</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">{</span><span style="--0:#D5D7D8;--1:#8F1500">metrics</span><span style="--0:#89DDFF;--1:#007474"> </span><span style="--0:#EE9080;--1:#8F1500">&#x26;&#x26;</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">LLM: {</span><span style="--0:#EEFFFF;--1:#00268F">metrics</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">llm_ms</span><span style="--0:#89DDFF;--1:#007474">}ms | TTS: {</span><span style="--0:#EEFFFF;--1:#00268F">metrics</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">tts_ms</span><span style="--0:#89DDFF;--1:#007474">}ms | First audio:{</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><span style="--0:#EEFFFF;--1:#00268F">metrics</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#00268F">first_audio_ms</span><span style="--0:#89DDFF;--1:#007474">}ms</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">)}</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></code></pre><div class="copy"><div aria-live="polite"></div><button data-copied="Copied!" data-code="import { useVoiceAgent } from &#x22;@cloudflare/voice/react&#x22;;function App() { const { status, transcript, interimTranscript, metrics, audioLevel, isMuted, startCall, endCall, toggleMute, } = useVoiceAgent({ agent: &#x22;MyVoiceAgent&#x22; }); return ( <div> <h1>Voice Agent</h1> <p>Status: {status}</p> <div> <button onClick={status === &#x22;idle&#x22; ? startCall : endCall}> {status === &#x22;idle&#x22; ? &#x22;Start Call&#x22; : &#x22;End Call&#x22;} </button> {status !== &#x22;idle&#x22; &#x26;&#x26; ( <button onClick={toggleMute}>{isMuted ? &#x22;Unmute&#x22; : &#x22;Mute&#x22;}</button> )} </div> {interimTranscript &#x26;&#x26; ( <p> <em>{interimTranscript}</em> </p> )} {transcript.map((msg, i) => ( <p key={i}> <strong>{msg.role}:</strong> {msg.text} </p> ))} {metrics &#x26;&#x26; ( <p> LLM: {metrics.llm_ms}ms | TTS: {metrics.tts_ms}ms | First audio:{&#x22; &#x22;} {metrics.first_audio_ms}ms </p> )} </div> );}"><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> <p>The <code dir="auto">status</code> field cycles through <code dir="auto">"idle"</code> → <code dir="auto">"listening"</code> → <code dir="auto">"thinking"</code> → <code dir="auto">"speaking"</code> → <code dir="auto">"listening"</code>, giving you everything you need to build a responsive UI.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="5-run-it">5. Run it</h2><a class="anchor-link" href="#5-run-it"><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">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="npm run dev"><div></div></button></div></figure></div> <p>Open the app in your browser, select <strong>Start Call</strong>, and speak. You will see the transcript appear in real time, and the agent's response will play through your speakers.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="adding-pipeline-hooks">Adding pipeline hooks</h2><a class="anchor-link" href="#adding-pipeline-hooks"><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>You can intercept and transform data at each stage of the pipeline. For example, filter out short transcripts (noise) and adjust pronunciation before TTS:</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-5308" id="tab-5308" 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-5309" id="tab-5309" 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-5308" aria-labelledby="tab-5308" 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">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">MyVoiceAgent</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">VoiceAgent</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">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#57C78F;--1:#00783C">afterTranscribe</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</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">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">transcript</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&#x3C;</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">3</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><span style="--0:#D5D7D8;--1:#8F1500">transcript</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:#57C78F;--1:#00783C">beforeSynthesize</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">text</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</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:#EEFFFF;--1:#00268F">text</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">replace</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#89DDFF;--1:#446E7F">AI</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#8EA7ED;--1:#00268F">g</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"A.I."</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"> </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">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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="export class MyVoiceAgent extends VoiceAgent { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); afterTranscribe(transcript, connection) { if (transcript.length < 3) return null; return transcript; } beforeSynthesize(text, connection) { return text.replace(/\bAI\b/g, &#x22;A.I.&#x22;); } async onTurn(transcript, context) { return &#x22;You said: &#x22; + transcript; }}"><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-5309" aria-labelledby="tab-5309" 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">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">MyVoiceAgent</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">VoiceAgent</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</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 style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAIFluxSTT</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">WorkersAITTS</span><span style="--0:#EEFFFF;--1:#62676A">(</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:#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 class="indent"> </span><span style="--0:#57C78F;--1:#00783C">afterTranscribe</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Connection</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">if</span><span style="--0:#EEFFFF;--1:#62676A"> (</span><span style="--0:#EEFFFF;--1:#00268F">transcript</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#EEFFFF;--1:#9D5600">length</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#EE9080;--1:#8F1500">&#x3C;</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">3</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><span style="--0:#D5D7D8;--1:#8F1500">transcript</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:#57C78F;--1:#00783C">beforeSynthesize</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">text</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">connection</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">Connection</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:#EEFFFF;--1:#00268F">text</span><span style="--0:#89DDFF;--1:#007474">.</span><span style="--0:#57C78F;--1:#00783C">replace</span><span style="--0:#EEFFFF;--1:#62676A">(</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#89DDFF;--1:#446E7F">AI</span><span style="--0:#EE9080;--1:#8F1500">\b</span><span style="--0:#FDDA68;--1:#A84E00">/</span><span style="--0:#8EA7ED;--1:#00268F">g</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"A.I."</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"> </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">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">VoiceTurnContext</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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="export class MyVoiceAgent extends VoiceAgent<Env> { transcriber = new WorkersAIFluxSTT(this.env.AI); tts = new WorkersAITTS(this.env.AI); afterTranscribe(transcript: string, connection: Connection) { if (transcript.length < 3) return null; return transcript; } beforeSynthesize(text: string, connection: Connection) { return text.replace(/\bAI\b/g, &#x22;A.I.&#x22;); } async onTurn(transcript: string, context: VoiceTurnContext) { return &#x22;You said: &#x22; + transcript; }}"><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> <p>Returning <code dir="auto">null</code> from <code dir="auto">afterTranscribe</code> drops the utterance entirely — useful for filtering noise or very short transcripts.</p> <div tabindex="-1" class="heading-wrapper level-h2"><h2 id="using-third-party-providers">Using third-party providers</h2><a class="anchor-link" href="#using-third-party-providers"><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>Swap in third-party STT or TTS providers without changing your agent logic:</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-5310" id="tab-5310" 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-5311" id="tab-5311" 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-5310" aria-labelledby="tab-5310" 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">ElevenLabsTTS</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/voice-elevenlabs"</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">DeepgramSTT</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/voice-deepgram"</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">MyVoiceAgent</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">VoiceAgent</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">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">DeepgramSTT</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">DEEPGRAM_API_KEY</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:#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 class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ElevenLabsTTS</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">ELEVENLABS_API_KEY</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">voiceId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"21m00Tcm4TlvDq8ikWAM"</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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 { ElevenLabsTTS } from &#x22;@cloudflare/voice-elevenlabs&#x22;;import { DeepgramSTT } from &#x22;@cloudflare/voice-deepgram&#x22;;export class MyVoiceAgent extends VoiceAgent { transcriber = new DeepgramSTT({ apiKey: this.env.DEEPGRAM_API_KEY, }); tts = new ElevenLabsTTS({ apiKey: this.env.ELEVENLABS_API_KEY, voiceId: &#x22;21m00Tcm4TlvDq8ikWAM&#x22;, }); async onTurn(transcript, context) { return &#x22;You said: &#x22; + transcript; }}"><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-5311" aria-labelledby="tab-5311" 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">ElevenLabsTTS</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/voice-elevenlabs"</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">DeepgramSTT</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/voice-deepgram"</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">MyVoiceAgent</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">VoiceAgent</span><span style="--0:#89DDFF;--1:#007474">&#x3C;</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 style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">transcriber</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">DeepgramSTT</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">DEEPGRAM_API_KEY</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:#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 class="indent"><span style="--0:#EEFFFF"> </span></span><span style="--0:#EEFFFF;--1:#00268F">tts</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:#EE9080;--1:#8F1500">new</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">ElevenLabsTTS</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">apiKey</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </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">ELEVENLABS_API_KEY</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">voiceId</span><span style="--0:#89DDFF;--1:#007474">:</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#FDDA68;--1:#A84E00">"21m00Tcm4TlvDq8ikWAM"</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:#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 class="indent"> </span><span style="--0:#EE9080;--1:#8F1500">async</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#57C78F;--1:#00783C">onTurn</span><span style="--0:#89DDFF;--1:#007474">(</span><span style="--0:#B59EE1;--1:#7C008F">transcript</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">string</span><span style="--0:#89DDFF;--1:#007474">,</span><span style="--0:#EEFFFF;--1:#62676A"> </span><span style="--0:#B59EE1;--1:#7C008F">context</span><span style="--0:#EE9080;--1:#8F1500">:</span><span style="--0:#EEFFFF;--1:#007474"> </span><span style="--0:#57C78F;--1:#00783C">VoiceTurnContext</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:#FDDA68;--1:#A84E00">"You said: "</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:#D5D7D8;--1:#8F1500">transcript</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 { ElevenLabsTTS } from &#x22;@cloudflare/voice-elevenlabs&#x22;;import { DeepgramSTT } from &#x22;@cloudflare/voice-deepgram&#x22;;export class MyVoiceAgent extends VoiceAgent<Env> { transcriber = new DeepgramSTT({ apiKey: this.env.DEEPGRAM_API_KEY, }); tts = new ElevenLabsTTS({ apiKey: this.env.ELEVENLABS_API_KEY, voiceId: &#x22;21m00Tcm4TlvDq8ikWAM&#x22;, }); async onTurn(transcript: string, context: VoiceTurnContext) { return &#x22;You said: &#x22; + transcript; }}"><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-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/voice/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Voice agents API reference</span> </a> <span class="description astro-lyux3snc">Full reference for withVoice, withVoiceInput, React hooks, VoiceClient, and all providers.</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/communication-channels/chat/chat-agents/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Chat agents</span> </a> <span class="description astro-lyux3snc">Build text-based AI chat with AIChatAgent and useAgentChat.</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/operations/using-ai-models/" class="astro-lyux3snc"> <span class="title astro-lyux3snc">Using AI models</span> </a> <span class="description astro-lyux3snc">Use Workers AI, OpenAI, Anthropic, Gemini, or any provider with your agents.</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/examples/slack-agent/" 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">Slack agent</span> </span> </a> <a href="/agents/examples/browser-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">Browser 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/voice-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-03T15:55:00.000Z">Jun 3, 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 ý Note ចំណាំ

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.
  • 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 đủ.
  • 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.
  • This is a summary on Orange Cloud Learning Hub — it does not replace the official documentation.
  • Open the Official docs link below for CLI commands, code snippets, and full screenshots.
  • Cloudflare docs change frequently — verify the Last reviewed date on the official page before production use.
  • នេះគឺជាការសង្ខេបនៅលើ Orange Cloud Learning Hub — វាមិនជំនួសឯកសារផ្លូវការទេ។
  • បើកតំណឯកសារផ្លូវការខាងក្រោមសម្រាប់ពាក្យបញ្ជា CLI កូដ snippets និងរូបថតអេក្រង់ពេញ។
  • Cloudflare ឯកសារផ្លាស់ប្តូរជាញឹកញាប់ — ផ្ទៀងផ្ទាត់កាលបរិច្ឆេទដែលបានពិនិត្យចុងក្រោយនៅលើទំព័រផ្លូវការមុនពេលប្រើប្រាស់ផលិតកម្ម។

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. ខ្លឹមសារលម្អិតមិនទាន់ធ្វើសមកាល — បើកឯកសារផ្លូវការ ឬរត់ 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). មើលមគ្គុទ្ទេសក៍ពេញលើ developers.cloudflare.com (រូបភាព, tab កំណត់)។

Tài liệu gốc ↗ Official docs ↗ ឯកសារផ្លូវការ ↗