@astralbeam/sdk 0.13.4 → 0.13.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,7 +29,7 @@ Without npm or a bundler, import the same entry from jsDelivr in a module script
29
29
 
30
30
  ```html
31
31
  <script type="module">
32
- import { mountAstralBeamChat } from "https://cdn.jsdelivr.net/npm/@astralbeam/sdk@0.13.4/dist/client.js"
32
+ import { mountAstralBeamChat } from "https://cdn.jsdelivr.net/npm/@astralbeam/sdk@0.13.6/dist/client.js"
33
33
 
34
34
  mountAstralBeamChat(document.getElementById("sidebar"), {})
35
35
  </script>
@@ -129,6 +129,7 @@ widgets: {
129
129
 
130
130
  - Schemas are plain JSON Schema, or any [Standard Schema](https://standardschema.dev) validator (Zod, Valibot, ArkType).
131
131
  - Only a Standard Schema validates input in the browser. With plain JSON Schema, treat input as untrusted.
132
+ - Return plain JSON values from tools, with no `undefined` fields. If a result cannot be sent, the action may still have happened.
132
133
 
133
134
  ## Documentation
134
135
 
@@ -164,7 +165,9 @@ There is no root export. Conversation history is not built yet.
164
165
 
165
166
  Types resolve under every TypeScript module resolution mode, including classic `"moduleResolution": "node"`. Requires TypeScript 5.0 or later because declarations use `const` type parameters, which fail to parse on TypeScript 4.x.
166
167
 
167
- ## Example
168
+ ## Examples
169
+
170
+ [`examples/linearity-react`](../examples/linearity-react) is a TanStack Start and shadcn/ui project tracker with two workspaces, localStorage persistence, and an assistant named Astro. It demonstrates validated tools, live issue cards, tenant switching, and a Basic Auth gate for a hosted playground.
168
171
 
169
172
  [`examples/todos`](../examples/todos) embeds the sidebar and a tenant-scoped user listing in a minimal TanStack Start app. Both use the same demo token route. The app also demonstrates host tools over live React state and a `todoCard` widget, with no Tailwind or shadcn/ui of its own.
170
173
 
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import{s as e}from"./constants-CgaMxV3q.js";import{t}from"./debug-qLts7gEt.js";function n(e,t,n,r){let i=n.colorScheme??`system`,a=i===`dark`||i===`system`&&r;e.classList.toggle(`dark`,a);for(let n of t)e.style.removeProperty(n);t.clear();let o={...n.theme?.light,...a?n.theme?.dark:void 0};for(let[n,r]of Object.entries(o))n.startsWith(`--`)&&(e.style.setProperty(n,r),t.add(n));return{colorScheme:i,dark:a}}function r(e){return e}function i(e){return e}function a(e,t){return s(e,t,`tenants`)}function o(e,t){return s(e,t,`users`)}function s(t,n,r){let i=t.shadowRoot??t.attachShadow({mode:`open`}),a=document.createElement(`div`);a.className=`${e} bg-transparent`,a.style.height=`100%`,i.append(a);let o=matchMedia(`(prefers-color-scheme: dark)`),s={options:{...n},kind:r,shadow:i,container:a,media:o,variables:new Set,disposed:!1},f=()=>c(s);return f(),o.addEventListener(`change`,f),l(s),{update:e=>u(s,e),refresh:()=>{!s.disposed&&s.renderer&&s.runtime.refreshListing(s.renderer)},reset:()=>{!s.disposed&&s.renderer&&s.runtime.resetListing(s.renderer)},unmount:()=>d(s,f)}}function c({options:e,media:t,container:r,variables:i}){n(r,i,e,t.matches)}async function l(e){e.retryLoad?.remove();try{if(e.runtime=await import(`./listings-BQZUPClK.js`),e.disposed)return;e.renderer=e.runtime.renderListing(e.shadow,e.container,e.options,e.kind)}catch{if(e.disposed)return;e.retryLoad=document.createElement(`button`),e.retryLoad.textContent=`Could not load directory. Retry`,e.retryLoad.onclick=()=>void l(e),e.container.append(e.retryLoad)}}function u(e,t){e.disposed||(e.options={...e.options,...t},c(e),e.renderer&&e.runtime.updateListing(e.renderer,e.options))}function d(e,t){e.disposed||(e.disposed=!0,e.media.removeEventListener(`change`,t),e.renderer&&e.runtime.disposeListing(e.renderer),e.container.remove())}function f(r,i){let a={...i},o=t(a.debug);o?.(`mount`,`mounting chat widget`,{agentId:a.agentId??`(organization default)`,title:a.title??`AstralBeam`,showHeader:a.showHeader??!0,emptyTitle:a.emptyTitle??`Ask the assistant`,emptyDescription:a.emptyDescription??`It can answer questions and act through this app's own tools and widgets.`,apiUrl:a.apiUrl??`https://app.astralbeam.ai/api`,authentication:`configured`,colorScheme:a.colorScheme??`system`,theme:a.theme,tools:Object.keys(a.tools??{}),widgets:Object.keys(a.widgets??{}),attachments:a.attachments??!0});let s=r.shadowRoot??r.attachShadow({mode:`open`}),c=document.createElement(`div`);c.className=e,c.style.height=`100%`,s.append(c);let l=matchMedia(`(prefers-color-scheme: dark)`),u=new Set,d=()=>{let{colorScheme:e,dark:t}=n(c,u,a,l.matches);o?.(`theme`,`color scheme "${e}" resolved to ${t?`dark`:`light`}`,{themeVariables:[...u]})};d(),l.addEventListener(`change`,d);let f=!1,p;return import(`./widget-Dq9yzJIB.js`).then(({renderChat:e})=>{o?.(`mount`,`chat chunk loaded`),f||(p=e(s,c,a))}),{update:e=>{a={...a,...e},o=t(a.debug),o?.(`mount`,`options updated`,{changed:Object.keys(e)}),d(),p?.update(a)},reset:()=>p?.reset(),stop:()=>p?.stop(),unmount:()=>{o?.(`mount`,`unmounting chat widget`),f=!0,l.removeEventListener(`change`,d),p?.dispose(),p=void 0,c.remove()}}}export{r as defineTool,i as defineWidget,f as mountAstralBeamChat,a as mountAstralBeamTenantList,o as mountAstralBeamTenantUserList};
1
+ import{s as e}from"./constants-CgaMxV3q.js";import{t}from"./debug-qLts7gEt.js";function n(e,t,n,r){let i=n.colorScheme??`system`,a=i===`dark`||i===`system`&&r;e.classList.toggle(`dark`,a);for(let n of t)e.style.removeProperty(n);t.clear();let o={...n.theme?.light,...a?n.theme?.dark:void 0};for(let[n,r]of Object.entries(o))n.startsWith(`--`)&&(e.style.setProperty(n,r),t.add(n));return{colorScheme:i,dark:a}}function r(e){return e}function i(e){return e}function a(e,t){return s(e,t,`tenants`)}function o(e,t){return s(e,t,`users`)}function s(t,n,r){let i=t.shadowRoot??t.attachShadow({mode:`open`}),a=document.createElement(`div`);a.className=`${e} bg-transparent`,a.style.height=`100%`,i.append(a);let o=matchMedia(`(prefers-color-scheme: dark)`),s={options:{...n},kind:r,shadow:i,container:a,media:o,variables:new Set,disposed:!1},f=()=>c(s);return f(),o.addEventListener(`change`,f),l(s),{update:e=>u(s,e),refresh:()=>{!s.disposed&&s.renderer&&s.runtime.refreshListing(s.renderer)},reset:()=>{!s.disposed&&s.renderer&&s.runtime.resetListing(s.renderer)},unmount:()=>d(s,f)}}function c({options:e,media:t,container:r,variables:i}){n(r,i,e,t.matches)}async function l(e){e.retryLoad?.remove();try{if(e.runtime=await import(`./listings-BQZUPClK.js`),e.disposed)return;e.renderer=e.runtime.renderListing(e.shadow,e.container,e.options,e.kind)}catch{if(e.disposed)return;e.retryLoad=document.createElement(`button`),e.retryLoad.textContent=`Could not load directory. Retry`,e.retryLoad.onclick=()=>void l(e),e.container.append(e.retryLoad)}}function u(e,t){e.disposed||(e.options={...e.options,...t},c(e),e.renderer&&e.runtime.updateListing(e.renderer,e.options))}function d(e,t){e.disposed||(e.disposed=!0,e.media.removeEventListener(`change`,t),e.renderer&&e.runtime.disposeListing(e.renderer),e.container.remove())}function f(r,i){let a={...i},o=t(a.debug);o?.(`mount`,`mounting chat widget`,{agentId:a.agentId??`(organization default)`,title:a.title??`AstralBeam`,showHeader:a.showHeader??!0,emptyTitle:a.emptyTitle??`Ask the assistant`,emptyDescription:a.emptyDescription??`It can answer questions and act through this app's own tools and widgets.`,apiUrl:a.apiUrl??`https://app.astralbeam.ai/api`,authentication:`configured`,colorScheme:a.colorScheme??`system`,theme:a.theme,tools:Object.keys(a.tools??{}),widgets:Object.keys(a.widgets??{}),attachments:a.attachments??!0});let s=r.shadowRoot??r.attachShadow({mode:`open`}),c=document.createElement(`div`);c.className=e,c.style.height=`100%`,s.append(c);let l=matchMedia(`(prefers-color-scheme: dark)`),u=new Set,d=()=>{let{colorScheme:e,dark:t}=n(c,u,a,l.matches);o?.(`theme`,`color scheme "${e}" resolved to ${t?`dark`:`light`}`,{themeVariables:[...u]})};d(),l.addEventListener(`change`,d);let f=!1,p;return import(`./widget-C31rEqSh.js`).then(({renderChat:e})=>{o?.(`mount`,`chat chunk loaded`),f||(p=e(s,c,a))}),{update:e=>{a={...a,...e},o=t(a.debug),o?.(`mount`,`options updated`,{changed:Object.keys(e)}),d(),p?.update(a)},reset:()=>p?.reset(),stop:()=>p?.stop(),unmount:()=>{o?.(`mount`,`unmounting chat widget`),f=!0,l.removeEventListener(`change`,d),p?.dispose(),p=void 0,c.remove()}}}export{r as defineTool,i as defineWidget,f as mountAstralBeamChat,a as mountAstralBeamTenantList,o as mountAstralBeamTenantUserList};
@@ -7840,6 +7840,11 @@ function buildHostTools(tools, debug) {
7840
7840
  }
7841
7841
  try {
7842
7842
  const output = await tool.execute(validated);
7843
+ try {
7844
+ canonicalInterruptJson(output);
7845
+ } catch {
7846
+ throw new Error(`Tool "${name}" ran, but its result is not JSON-compatible. Its changes may already be applied. Read current state before retrying. Return plain JSON values and omit undefined fields.`);
7847
+ }
7843
7848
  debug?.("tool", `host tool "${name}" returned`, { output });
7844
7849
  return output;
7845
7850
  } catch (error) {
package/dist/core.js CHANGED
@@ -1,2 +1,2 @@
1
- import { S as SANDBOX_WRITE_FILE_TOOL, _ as SANDBOX_LIST_FILES_TOOL, a as describeSandboxCommandRun, b as SANDBOX_RUN_COMMAND_TOOL, c as readSandboxCommandRun, d as hasPendingToolRun, f as isSettledToolCall, g as RENDER_WIDGET_TOOL, h as ASK_QUESTIONNAIRE_TOOL, i as collectSandboxActivity, l as readSandboxFileWrite, m as buildAgentTools, o as isSandboxTool, p as lastPartInProgress, r as createAstralBeamChat, s as readSandboxArtifact, t as defineTool, u as sandboxRefusal, v as SANDBOX_PUBLISH_ARTIFACT_TOOL, x as SANDBOX_STATUS_EVENT, y as SANDBOX_READ_FILE_TOOL } from "./core-DfA5fxd0.js";
1
+ import { S as SANDBOX_WRITE_FILE_TOOL, _ as SANDBOX_LIST_FILES_TOOL, a as describeSandboxCommandRun, b as SANDBOX_RUN_COMMAND_TOOL, c as readSandboxCommandRun, d as hasPendingToolRun, f as isSettledToolCall, g as RENDER_WIDGET_TOOL, h as ASK_QUESTIONNAIRE_TOOL, i as collectSandboxActivity, l as readSandboxFileWrite, m as buildAgentTools, o as isSandboxTool, p as lastPartInProgress, r as createAstralBeamChat, s as readSandboxArtifact, t as defineTool, u as sandboxRefusal, v as SANDBOX_PUBLISH_ARTIFACT_TOOL, x as SANDBOX_STATUS_EVENT, y as SANDBOX_READ_FILE_TOOL } from "./core-c6eS1h0R.js";
2
2
  export { ASK_QUESTIONNAIRE_TOOL, RENDER_WIDGET_TOOL, SANDBOX_LIST_FILES_TOOL, SANDBOX_PUBLISH_ARTIFACT_TOOL, SANDBOX_READ_FILE_TOOL, SANDBOX_RUN_COMMAND_TOOL, SANDBOX_STATUS_EVENT, SANDBOX_WRITE_FILE_TOOL, buildAgentTools, collectSandboxActivity, createAstralBeamChat, defineTool, describeSandboxCommandRun, hasPendingToolRun, isSandboxTool, isSettledToolCall, lastPartInProgress, readSandboxArtifact, readSandboxCommandRun, readSandboxFileWrite, sandboxRefusal };
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as CORE_OPTION_KEYS, r as createAstralBeamChat } from "./core-DfA5fxd0.js";
1
+ import { n as CORE_OPTION_KEYS, r as createAstralBeamChat } from "./core-c6eS1h0R.js";
2
2
  import { M as DEFAULT_COLOR_SCHEME } from "./api-DiwSihrG.js";
3
3
  import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -17,4 +17,4 @@ import{A as e,An as t,D as n,Dn as r,E as i,En as a,Gt as o,H as s,Kn as c,Kt as
17
17
  `);r=s.pop()||``;for(let e of s){let t=e.endsWith(`\r`)?e.slice(0,-1):e;t.trim()&&(yield t)}}if(r+=n.decode(),r.trim()&&!t?.aborted)throw new zu}finally{e.releaseLock()}}function $u(e){return Ll(e)}function ed(e){let t=Q(e)?.model;if(typeof t==`string`)return t;let n=`usage`in e?e.usage:void 0;if(Array.isArray(n)){let e=n[0]?.model;if(typeof e==`string`)return e}}async function*td(e,t){let n,r,i,a;for await(let o of e){if(o===`id`||o.startsWith(`id:`)){let e=o===`id`?``:o.slice(3);a=e.startsWith(` `)?e.slice(1):e;continue}if(o.startsWith(`:`)||o.startsWith(`event:`)||o.startsWith(`retry:`))continue;let e=Ec(o);if(e===`[DONE]`){yield{chunk:Nc({type:Au.RUN_FINISHED,threadId:n??t?.threadId??``,runId:r??t?.runId??``,timestamp:Date.now()},{finishReason:`stop`,...i===void 0?{}:{model:i}})};return}let s=$u(JSON.parse(e));`threadId`in s&&typeof s.threadId==`string`&&(n=s.threadId),`runId`in s&&typeof s.runId==`string`&&(r=s.runId);let c=ed(s);c!==void 0&&(i=c);let l=a;a=void 0,yield{chunk:s,...l===void 0?{}:{id:l}}}}async function nd(e){if(!e.ok){if(e.status===401){let t=await e.clone().json().catch(()=>null);if(Nu(t))throw new Pu(t.error.provider)}throw Error(`HTTP error! status: ${e.status} ${e.statusText}`)}}async function rd(e,t,n,r,i){let a=await e(Zu(t,{threadId:i}),{method:`GET`,headers:{Accept:`application/json`,...n},credentials:r});await nd(a);let o=await a.json(),s=o.activeRun&&typeof o.activeRun.runId==`string`?{runId:o.activeRun.runId}:null,c=o.interrupts&&typeof o.interrupts.runId==`string`&&Array.isArray(o.interrupts.pending)&&o.interrupts.pending.length>0?{runId:o.interrupts.runId,pending:o.interrupts.pending}:null;return{messages:Array.isArray(o.messages)?o.messages:[],activeRun:s,interrupts:c}}async function id(e,t,n,r,i){let a=await e(Zu(t,{threadId:i}),{method:`GET`,headers:{Accept:`application/json`,...n},credentials:r});await nd(a);let o=await a.json();if(o===null)return{resumeSnapshot:null,activeRun:null};if(typeof o!=`object`||Array.isArray(o))throw Error(`Generation hydration expected a JSON object from ${t}, received ${Array.isArray(o)?`an array`:typeof o}.`);let s=o,c=s.activeRun&&typeof s.activeRun.runId==`string`?{runId:s.activeRun.runId}:null;return{resumeSnapshot:s.resumeSnapshot??null,activeRun:c}}async function*ad(e,t,n){await nd(e),yield*td(Qu(wc(e),t),n)}async function*od(e,t){for await(let{chunk:n}of ad(e,t))yield n}function sd(e,t,n,r){return async function*(i,a){let o;try{o=await e(t,{...n,headers:{...n.headers,...i},...a?{signal:a}:{}})}catch(e){throw new Bu(e)}yield*r(o,a)}}async function*cd(e,t,n){let r=Wu(n);for(;;){if(t?.aborted)return;let n=r.lastEventId===void 0?{}:{"Last-Event-ID":r.lastEventId},i=!1,a=!1;try{for await(let{chunk:o,id:s}of e(n,t))r.note(s)!==`duplicate`&&(a=!0,(o.type===`RUN_FINISHED`||o.type===`RUN_ERROR`)&&(i=!0),yield o)}catch(e){if(t?.aborted)return;if((e instanceof zu||e instanceof Bu)&&r.lastEventId!==void 0){await r.waitBeforeReconnect(a,t);continue}throw e}if(t?.aborted||i)return;if(r.lastEventId!==void 0){if(a){await r.waitBeforeReconnect(!0,t);continue}throw new Vu}return}}function ld(e){if(!e)throw Error(`Connection adapter is required`);let t=`connect`in e,n=`subscribe`in e,r=`send`in e;if(t&&(n||r))throw Error(`Connection adapter must provide either connect or both subscribe and send, not both modes`);if(n&&r){let t=e.joinRun?.bind(e),n=e.hydrate?.bind(e);return{subscribe:e.subscribe.bind(e),send:e.send.bind(e),...t?{joinRun:t}:{},...n?{hydrate:n}:{}}}if(!t)throw Error(`Connection adapter must provide either connect or both subscribe and send`);let i=[],a=[];function o(e,t){t&&Lu.set(e,t);let n=a.shift();n?n(e):i.push(e)}return{subscribe(e){let t=i.splice(0),n=[];return i=t,a=n,(async function*(){for(;!e?.aborted;){let r,i=t.shift();r=i===void 0?await new Promise(t=>{let r=()=>t(null);n.push(n=>{e?.removeEventListener(`abort`,r),t(n)}),e?.addEventListener(`abort`,r,{once:!0})}):i,r!==null&&(yield r)}})()},async send(t,n,r,i){let a=!1,s,c;try{let l=e.connect(t,n,r,i);for await(let e of l)`threadId`in e&&typeof e.threadId==`string`&&(s=e.threadId),`runId`in e&&typeof e.runId==`string`&&(c=e.runId),(e.type===`RUN_FINISHED`||e.type===`RUN_ERROR`)&&(a=!0),o(e,i?.runId);!r?.aborted&&!a&&o(Nc({type:Au.RUN_FINISHED,threadId:qu(s??i?.threadId,`threadId`),runId:qu(c??i?.runId,`runId`),timestamp:Date.now()},{finishReason:`stop`,model:`connect-wrapper`}),i?.runId)}catch(e){if(!r?.aborted&&!a)try{let t=e instanceof Error?e.message:`Unknown error in connect()`;o({type:Au.RUN_ERROR,threadId:qu(s??i?.threadId,`threadId`),runId:qu(c??i?.runId,`runId`),timestamp:Date.now(),message:t},i?.runId)}catch{}throw e}},...typeof e.joinRun==`function`?{joinRun:(t,n)=>e.joinRun(t,n)}:{},...(()=>{let t=e.hydrate;return typeof t==`function`?{hydrate:e=>t(e)}:{}})()}}function ud(e,t,n,r){let i=wl(e),a={...r.body,...n?.forwardedProps??{},...t};return{threadId:n?.threadId??Ku(`thread`),runId:n?.runId??Ku(`run`),...n?.parentRunId!==void 0&&{parentRunId:n.parentRunId},...n?.resume!==void 0&&{resume:n.resume},state:{},messages:i,tools:n?.clientTools??[],context:[],forwardedProps:a,data:{...a}}}function dd(e,t={}){return{async*connect(n,r,i,a){let o=typeof e==`function`?e():e,s=typeof t==`function`?await t():t,c={"Content-Type":`application/json`,...Ju(s.headers),...Ju(a?.headers),...Xu(a?.runId)},l=ud(n,r,a,s),u=s.fetchClient??fetch,d=i||s.signal;yield*cd(sd(u,o,{method:`POST`,headers:c,body:JSON.stringify(l),credentials:s.credentials||`same-origin`},(e,t)=>ad(e,t,{...a?.threadId===void 0?{}:{threadId:a.threadId},...a?.runId===void 0?{}:{runId:a.runId}})),d,s.reconnect)},async*joinRun(n,r){let i=typeof e==`function`?e():e,a=typeof t==`function`?await t():t,o=Zu(i,{offset:`-1`,runId:n}),s={...Ju(a.headers)},c=a.fetchClient??fetch,l=r||a.signal;yield*cd(sd(c,o,{method:`GET`,headers:s,credentials:a.credentials||`same-origin`},(e,t)=>ad(e,t,{runId:n})),l,a.reconnect)},async hydrate(n){let r=typeof e==`function`?e():e,i=typeof t==`function`?await t():t;return rd(i.fetchClient??fetch,r,Ju(i.headers),i.credentials||`same-origin`,n)},async hydrateGeneration(n){let r=typeof e==`function`?e():e,i=typeof t==`function`?await t():t;return id(i.fetchClient??fetch,r,Ju(i.headers),i.credentials||`same-origin`,n)}}}function fd(e){return{async*connect(t,n,r,i){if(!r)throw Error(`fetcherToConnectionAdapter requires an AbortSignal — the chat client always supplies one.`);if(!i)throw Error(`fetcherToConnectionAdapter requires a RunAgentInputContext — the chat client always supplies one.`);let a=await e({messages:t,data:n,threadId:i.threadId,runId:i.runId,...i.parentRunId===void 0?{}:{parentRunId:i.parentRunId},...i.resume===void 0?{}:{resume:i.resume}},{signal:r,headers:i.headers});a instanceof Response?yield*od(a,r):yield*pd(a,r)}}}async function*pd(e,t){if(t.aborted)return;let n=e[Symbol.asyncIterator](),r=new Promise(e=>{t.addEventListener(`abort`,()=>e({done:!0,value:void 0}),{once:!0})});try{for(;;){let e=await Promise.race([n.next(),r]);if(e.done)return;yield e.value}}finally{await n.return?.()}}function md(e){return e.resumable}function hd(e,t){let n=Cl(e.descriptor);return n?{...t,metadata:Sl(n)}:t}function gd(e){return`cancel`in e&&`clearResolution`in e}var _d=new Set([`invalid-payload`,`invalid-edited-args`,`invalid-tool-output`,`invalid-response-schema`,`unknown-interrupt`,`expired`,`stale`,`conflict`,`legacy-unsupported`]),vd=new Set([`incomplete-batch`,`item-validation-failed`,`unsupported-bulk-operation`,`async-resolver`,`inactive-transaction`,`mixed-provenance`,`transport`,`server`,`protocol`,`invalid-response-schema`,`expired`,`stale`,`conflict`,`legacy-submit-failed`]);function yd(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function bd(e){return yd(e)&&e.kind===`approval`&&typeof e.toolName==`string`&&`input`in e}function xd(e){return yd(e)&&e.kind===`client_tool`&&typeof e.toolName==`string`&&`input`in e}function Sd(e){return bd(e.metadata)||xd(e.metadata)}function Cd(e){return gl(e)}function wd(e){if(!yd(e.metadata))return!1;let t=e.metadata[ul];return!yd(t)||t.v!==void 0&&t.v!==1?!1:t.kind===`generic`||t.kind===`tool-approval`||t.kind===`client-tool-execution`||`definitionId`in t||`key`in t||`batchIndex`in t||`payloadSchemaHash`in t}function Td(e){if(!yd(e.metadata))return!1;let t=e.metadata[ul];return!yd(t)||t.kind!==`generic`?!1:`definitionId`in t||`key`in t||`batchIndex`in t||`payloadSchemaHash`in t}function Ed(e){return e.metadata?.[`tanstack:interruptPayload`]}function Dd(e){return e===`tanstack:client_tool_execution`||e===`client_tool_input`}function Od(e){if(e.responseSchema!==void 0)try{return Vc(Bc(e.responseSchema))}catch{return}}function kd(e){if(e!==void 0)try{return yl(e)}catch{return}}function Ad(e){return e!==null&&(typeof e==`object`||typeof e==`function`)&&`then`in e&&typeof e.then==`function`}function jd(e,t,n){if(e===void 0)return{valid:!0,payload:t};if(qc(e)){let r=e[`~standard`].validate(t),i=e=>e.issues?{code:n,message:e.issues[0]?.message??`Schema validation failed.`}:{valid:!0,payload:e.value};return Ad(r)?Promise.resolve(r).then(i):i(r)}return{valid:!0,payload:t}}function Md(e){for(let t of _d)if(t===e)return!0;return!1}function Nd(e){for(let t of vd)if(t===e)return!0;return!1}function Pd(e){if(!yd(e))return!1;let t=e.scope,n=e.code;return typeof n==`string`&&typeof e.message==`string`&&typeof e.retryable==`boolean`&&typeof e.threadId==`string`&&typeof e.interruptedRunId==`string`&&typeof e.generation==`number`?t===`item`?Md(n)&&typeof e.interruptId==`string`&&(e.source===`client`||e.source===`server`):t===`batch`&&Nd(n)&&Array.isArray(e.interruptIds)&&e.interruptIds.every(e=>typeof e==`string`)&&(e.source===`client`||e.source===`server`||e.source===`transport`):!1}function Fd(e){return Pd(e)?[e]:!yd(e)||!Array.isArray(e.errors)?[]:e.errors.every(Pd)?e.errors:[]}function Id(e,t){if(e.length!==t.length)return!1;let n=[...e].sort(),r=[...t].sort();return n.every((e,t)=>e===r[t])}function Ld(e,t){return e.threadId===t.threadId&&e.interruptedRunId===t.interruptedRunId&&e.generation===t.generation&&Id(e.interruptIds,t.interruptIds)}function Rd(e,t,n){let r=n.filter(e=>e.source!==`transport`),i=e=>t.includes(e)&&r.some(t=>Ld(e,t)),a=e.filter(e=>!i(e)),o=t.filter(e=>!r.some(t=>Ld(e,t)));return Object.freeze({rootErrors:Object.freeze([...a,...n]),submissionRootErrors:Object.freeze([...o,...r])})}function zd(e,t){if(e.threadId!==t.threadId||e.interruptedRunId!==t.interruptedRunId||e.generation!==t.generation)return!1;let n=t.resolutions.map(e=>e.interruptId);return e.scope===`item`?n.includes(e.interruptId):Id(e.interruptIds,n)}function Bd(e,t,n){let r=Od(e)??n?.responseSchemaHash;return $({v:1,kind:`generic`,interruptId:e.id,interruptedRunId:t.interruptedRunId,generation:t.generation,...r===void 0?{}:{responseSchemaHash:r},...e.expiresAt===void 0?{}:{expiresAt:e.expiresAt}})}function Vd(e,t){let n=$(e.descriptor),r=e.error===void 0?Object.freeze([]):Object.freeze([$(e.error)]),i=r[0];return{id:n.id,interruptId:n.id,reason:n.reason,...n.message===void 0?{}:{message:n.message},...n.responseSchema===void 0?{}:{responseSchema:n.responseSchema},...n.expiresAt===void 0?{}:{expiresAt:n.expiresAt},...n.metadata===void 0?{}:{metadata:n.metadata},threadId:t.threadId,interruptedRunId:t.interruptedRunId,generation:t.generation,status:e.status,errors:r,...i===void 0?{}:{error:i},canResolve:e.canResolve}}var Hd=class{options;hydration;items=[];snapshot=Object.freeze([]);rootErrors=Object.freeze([]);submissionRootErrors=Object.freeze([]);state=Object.freeze({interrupts:this.snapshot,pendingInterrupts:this.snapshot,interruptErrors:this.rootErrors,resuming:!1});activeTransaction;activeSubmissionOperation;retrySubmission;resuming=!1;tools;interruptDefinitions;constructor(e){this.options=e,this.tools=e.tools;let t=new Map;for(let n of e.interrupts??[]){if(t.has(n.id))throw Error(`Duplicate interrupt definition id: ${n.id}`);t.set(n.id,n)}this.interruptDefinitions=t}updateTools(e){this.tools=e}hydrate(e,t=`live`){this.activeSubmissionOperation=void 0,this.hydration={threadId:e.threadId,interruptedRunId:e.interruptedRunId,generation:e.generation,interrupts:$(e.interrupts)};let n=new Map;for(let t of e.interrupts){let e=Cd(t);e?.kind===`generic`&&e.definitionId!==void 0&&e.key!==void 0&&e.batchIndex!==void 0&&n.set(e.batchIndex,(n.get(e.batchIndex)??0)+1)}this.items=e.interrupts.map(t=>this.hydrateInterrupt(t,e,n)),this.rootErrors=Object.freeze([]),this.submissionRootErrors=Object.freeze([]),this.retrySubmission=void 0,this.resuming=!1,this.publish(t)}getInterrupts(){return this.snapshot}getState(){return this.state}getDescriptors(){return this.hydration?.interrupts??Object.freeze([])}hasValidatedFirstPartyGenericBatch(){return this.items.some(e=>e.kind===`generic`&&e.definition!==void 0)}reset(e){this.activeSubmissionOperation=void 0,this.hydration=void 0,this.items=[],this.snapshot=Object.freeze([]),e?.preserveRootErrors!==!0&&(this.rootErrors=Object.freeze([]),this.submissionRootErrors=Object.freeze([])),this.retrySubmission=void 0,this.resuming=!1,this.state=Object.freeze({interrupts:this.snapshot,pendingInterrupts:this.snapshot,interruptErrors:this.rootErrors,resuming:!1}),this.options.onChange?.(e?.source??`live`)}getInterruptErrors(){return this.rootErrors}getResuming(){return this.resuming}resolve(e){if(this.assertRootMutable(),typeof e==`boolean`){this.resolveBooleanBulk(e);return}this.resolveTransaction(e)}cancel(){this.assertRootMutable(),this.invalidateRetry();for(let e of this.items)md(e)&&(e.validationGeneration++,e.resolution=Object.freeze(hd(e,{interruptId:e.descriptor.id,status:`cancelled`})),e.status=`staged`,e.error=void 0);this.publish(),this.maybeSubmit()}retry(){if(this.resuming)throw Error(`Interrupt submission is already active.`);let e=this.retrySubmission;if(!e){this.addRootError(`transport`,`There is no retryable interrupt submission.`,!1);return}this.submitBatch(e)}resolveClientToolOutput(e,t){let n=this.items.find(t=>t.kind===`client-tool-execution`&&t.binding?.kind===`client-tool-execution`&&t.binding.toolCallId===e||t.kind===`generic`&&Dd(t.descriptor.reason)&&t.descriptor.toolCallId===e&&xd(t.descriptor.metadata));return n?(this.resolveItem(n.descriptor.id,t),!0):!1}resolveToolApprovalDecision(e,t){let n=this.items.find(t=>t.descriptor.id===e&&(t.kind===`tool-approval`||t.kind===`generic`&&t.descriptor.reason===`approval_required`&&bd(t.descriptor.metadata)));return n?(this.resolveItem(n.descriptor.id,{approved:t}),!0):!1}hydrateInterrupt(e,t,n){let r=$(e),i=Cd(r),a=i===void 0&&Sd(r);if(i===void 0&&!a)return wd(r)?{descriptor:r,binding:Bd(r,t,void 0),kind:`generic`,status:`error`,canResolve:!1,resumable:!1,error:this.itemError(r.id,`stale`,`The interrupt binding is invalid or incomplete.`),validationGeneration:0}:{descriptor:r,binding:void 0,kind:`unbound`,status:`pending`,canResolve:!1,resumable:!1,validationGeneration:0};let o=i!==void 0&&i.interruptId===r.id&&i.interruptedRunId===t.interruptedRunId&&i.generation===t.generation&&Od(r)===i.responseSchemaHash,s=i!==void 0&&i.interruptId===r.id&&i.interruptedRunId===t.interruptedRunId&&i.generation===t.generation&&i.responseSchemaHash===(Od(r)??i.responseSchemaHash);if(i!==void 0&&Td(r)&&(!s||i.kind!==`generic`||i.definitionId===void 0||i.key===void 0||i.batchIndex===void 0))return{descriptor:r,binding:Bd(r,t,i),kind:`generic`,status:`error`,canResolve:!1,resumable:!1,error:this.itemError(r.id,`stale`,`The interrupt binding does not match this interrupted run.`),validationGeneration:0};if(s&&i.kind===`tool-approval`){let e=this.tools?.find(e=>e.name===i.toolName);if(e?.needsApproval===!0&&r.toolCallId===i.toolCallId)try{let t=cl(e.approvalSchema,e.inputSchema);if(ll(e.inputSchema)===i.inputSchemaHash&&t.approvalSchemaHash===i.approvalSchemaHash&&t.responseSchemaHash===i.responseSchemaHash)return{descriptor:r,binding:$(i),kind:`tool-approval`,status:`pending`,canResolve:!0,resumable:!0,tool:e,validationGeneration:0}}catch{}}if(s&&i.kind===`client-tool-execution`){let e=this.tools?.find(e=>e.name===i.toolName);if(e!==void 0&&r.toolCallId===i.toolCallId&&ll(e.outputSchema)===i.outputSchemaHash)return{descriptor:r,binding:$(i),kind:`client-tool-execution`,status:`pending`,canResolve:!0,resumable:!0,tool:e,validationGeneration:0}}if(i!==void 0&&i.kind===`generic`&&i.definitionId!==void 0&&i.key!==void 0&&i.batchIndex!==void 0&&i.key.length>0&&n.get(i.batchIndex)!==1)return{descriptor:r,binding:$(i),kind:`generic`,status:`error`,canResolve:!1,resumable:!1,error:this.itemError(r.id,`stale`,`Generic interrupt batch contains a duplicate batchIndex.`),validationGeneration:0};if(o&&i.kind===`generic`&&i.definitionId!==void 0&&i.key!==void 0&&i.batchIndex!==void 0&&i.key.length>0&&n.get(i.batchIndex)===1){let e=this.interruptDefinitions.get(i.definitionId);if(e!==void 0&&kd(e.responseSchema)===i.responseSchemaHash&&(e.payloadSchema===void 0?i.payloadSchemaHash===void 0:i.payloadSchemaHash===kd(e.payloadSchema))){let t=Ed(r);return{descriptor:r,binding:$(i),definition:e,kind:`generic`,status:`pending`,canResolve:!0,resumable:!0,...t===void 0?{}:{payload:$(t)},validationGeneration:0}}}let c=a||i!==void 0&&i.interruptId===r.id&&i.interruptedRunId===t.interruptedRunId&&i.generation===t.generation&&(i.kind!==`generic`||Od(r)===void 0||i.responseSchemaHash===Od(r));return{descriptor:r,binding:Bd(r,t,i),kind:`generic`,status:`pending`,canResolve:c,resumable:c,validationGeneration:0}}buildSnapshot(e){let t=this.requireHydration(),n=this.items.filter(e=>e.kind!==`client-tool-execution`&&e.status!==`submitting`).map(n=>{let r=Vd(n,t);if(n.kind===`unbound`||n.binding===void 0){let e={...r,kind:`unbound`,canResolve:!1};return Object.freeze(e)}if(n.kind===`tool-approval`&&n.binding.kind===`tool-approval`){let t=$(n.binding),i={...r,kind:`tool-approval`,binding:t,toolName:n.binding.toolName,toolCallId:n.binding.toolCallId,originalArgs:$(n.binding.originalArgs),cancel:()=>this.cancelItem(n.descriptor.id,e),clearResolution:()=>this.clearItem(n.descriptor.id,e),resolveInterrupt:(t,r)=>{let i=yd(r)?r:void 0;this.resolveItem(n.descriptor.id,{approved:t,...t&&i?.editedArgs!==void 0?{editedArgs:i.editedArgs}:{},...i?.payload===void 0?{}:{payload:i.payload}},e)}};return Object.freeze(i)}let i=n.binding.kind===`generic`?$(n.binding):$({v:1,kind:`generic`,interruptId:n.descriptor.id,interruptedRunId:t.interruptedRunId,generation:t.generation,...typeof n.binding.responseSchemaHash==`string`?{responseSchemaHash:n.binding.responseSchemaHash}:{}});if(n.definition!==void 0&&n.binding.kind===`generic`){let t={...r,kind:`generic`,definitionId:n.definition.id,key:n.binding.key??``,payload:n.payload,binding:i,cancel:()=>this.cancelItem(n.descriptor.id,e),clearResolution:()=>this.clearItem(n.descriptor.id,e),resolveInterrupt:t=>this.resolveItem(n.descriptor.id,t,e)};return Object.freeze(t)}let a={...r,kind:`generic`,binding:i,cancel:()=>this.cancelItem(n.descriptor.id,e),clearResolution:()=>this.clearItem(n.descriptor.id,e),resolveInterrupt:t=>this.resolveItem(n.descriptor.id,t,e)};return Object.freeze(a)});return Object.freeze(n)}publish(e=`live`){if(!this.hydration){this.snapshot=Object.freeze([]),this.state=Object.freeze({interrupts:this.snapshot,pendingInterrupts:this.snapshot,interruptErrors:this.rootErrors,resuming:this.resuming}),this.options.onChange?.(e);return}this.snapshot=this.buildSnapshot(),this.state=Object.freeze({interrupts:this.snapshot,pendingInterrupts:this.snapshot,interruptErrors:this.rootErrors,resuming:this.resuming}),this.options.onChange?.(e)}resolveItem(e,t,n){this.assertItemMutable(n);let r=this.findItem(e);if(this.invalidateRetry(),!r.canResolve){r.status=`error`,r.error=this.itemError(e,`invalid-response-schema`,`The interrupt response schema is invalid and cannot be resolved.`),n||this.publish();return}let i=++r.validationGeneration,a=this.validateCandidate(r,t);if(Ad(a)){r.status=`validating`,r.error=void 0,n||this.publish(),Promise.resolve(a).then(e=>{i===r.validationGeneration&&this.applyValidation(r,e,n)}).catch(e=>{i===r.validationGeneration&&this.applyValidation(r,{code:this.validationCode(r),message:e instanceof Error?e.message:String(e)},n)});return}this.applyValidation(r,a,n)}cancelItem(e,t){this.assertItemMutable(t);let n=this.findItem(e);this.invalidateRetry(),n.validationGeneration++,n.resolution=Object.freeze(hd(n,{interruptId:e,status:`cancelled`})),n.status=`staged`,n.error=void 0,t||(this.publish(),this.maybeSubmit())}clearItem(e,t){this.assertItemMutable(t);let n=this.findItem(e);this.invalidateRetry(),n.validationGeneration++,n.resolution=void 0,n.error=void 0,n.status=`pending`,t||this.publish()}maybeSubmit(){let e=this.items.some(e=>e.kind===`generic`),t=this.items.filter(t=>md(t)&&!(e&&t.kind===`client-tool-execution`));if(t.length===0||t.some(e=>e.resolution===void 0||e.status!==`staged`))return;let n=this.requireHydration(),r=Uc(t.map(e=>e.resolution).filter(e=>e!==void 0)),i=Object.freeze({threadId:n.threadId,interruptedRunId:n.interruptedRunId,generation:n.generation,resolutions:r.resolutions,canonicalResolutions:r.canonicalResolutions,fingerprint:r.fingerprint});this.submitBatch(i)}applyValidation(e,t,n){if(!(`valid`in t)){e.status=`error`;let r=this.itemError(e.descriptor.id,t.code,t.message,t.path);e.error=r,e.kind===`client-tool-execution`&&(this.rootErrors=Object.freeze([...this.rootErrors.filter(t=>!(t.code===`item-validation-failed`&&t.interruptIds.includes(e.descriptor.id))),Object.freeze({scope:`batch`,code:`item-validation-failed`,message:r.message,source:`client`,retryable:!1,interruptIds:Object.freeze([e.descriptor.id]),threadId:r.threadId,interruptedRunId:r.interruptedRunId,generation:r.generation})])),n||this.publish();return}e.resolution=$(hd(e,{interruptId:e.descriptor.id,status:`resolved`,payload:t.payload})),e.status=`staged`,e.error=void 0,n||(this.publish(),this.maybeSubmit())}validateCandidate(e,t){if(e.kind===`generic`){let n=jd(e.definition?.responseSchema??e.descriptor.responseSchema,t,`invalid-payload`);if(e.definition===void 0)return n;let r=e=>`valid`in e?{valid:!0,payload:t}:e;return Ad(n)?Promise.resolve(n).then(r):r(n)}return e.kind===`client-tool-execution`?jd(e.tool?.outputSchema,t,`invalid-tool-output`):this.validateApprovalCandidate(e,t)}validateApprovalCandidate(e,t){if(!yd(t)||typeof t.approved!=`boolean`)return{code:`invalid-payload`,message:`Tool approval resolutions require an approved boolean.`};let n=t.approved,r=t.editedArgs;if(!n&&r!==void 0)return{code:`invalid-edited-args`,message:`Rejected tool approvals cannot edit tool arguments.`};if(n&&r!==void 0){let n=jd(e.tool?.inputSchema,r,`invalid-edited-args`);return Ad(n)?Promise.resolve(n).then(n=>`valid`in n?this.validateApprovalPayload(e,t,n.payload):n):`valid`in n?this.validateApprovalPayload(e,t,n.payload):n}return this.validateApprovalPayload(e,t,void 0)}validateApprovalPayload(e,t,n){let r=t.approved===!0,i=this.approvalBranchSchema(e.tool,r),a=t.payload;if(i===void 0&&a!==void 0)return{code:`invalid-payload`,message:`This approval branch does not accept a payload.`};if(i!==void 0&&a===void 0)return{code:`invalid-payload`,message:`This approval branch requires a payload.`};let o=jd(i,a,`invalid-payload`),s=e=>`valid`in e?{valid:!0,payload:{approved:r,...n===void 0?{}:{editedArgs:n},...i===void 0?{}:{payload:e.payload}}}:e;return Ad(o)?Promise.resolve(o).then(s):s(o)}approvalBranchSchema(e,t){let n=e?.approvalSchema;return!yd(n)||!(`approve`in n||`reject`in n)?n:t?n.approve:n.reject}validationCode(e){return e.kind===`client-tool-execution`?`invalid-tool-output`:`invalid-payload`}resolveBooleanBulk(e){let t=this.items.filter(e=>md(e)&&e.kind!==`client-tool-execution`);if(!t.every(t=>t.kind===`tool-approval`&&this.approvalBranchSchema(t.tool,e)===void 0)||t.length===0){this.addRootError(`unsupported-bulk-operation`,`Boolean bulk resolution requires payloadless tool approvals.`,!1);return}this.invalidateRetry();for(let n of t)n.validationGeneration++,n.resolution=$({interruptId:n.descriptor.id,status:`resolved`,payload:{approved:e}}),n.status=`staged`,n.error=void 0;this.publish(),this.maybeSubmit()}resolveTransaction(e){let t=this.items.map(e=>({status:e.status,...e.resolution===void 0?{}:{resolution:e.resolution},...e.error===void 0?{}:{error:e.error},validationGeneration:e.validationGeneration})),n={active:!0};this.activeTransaction=n;let r=this.buildSnapshot(n).filter(gd),i;try{for(let t of r){let n=e(t);if(n!==void 0){i={code:Ad(n)?`async-resolver`:`inactive-transaction`,message:Ad(n)?`Interrupt transaction resolvers must be synchronous.`:`Interrupt transaction resolvers must return literal undefined.`};break}}i===void 0&&this.items.some(e=>md(e)&&e.kind!==`client-tool-execution`&&(e.resolution===void 0||e.status!==`staged`))&&(i={code:`incomplete-batch`,message:`Interrupt transaction did not resolve every item.`})}catch(e){i={code:`item-validation-failed`,message:e instanceof Error?e.message:String(e)}}finally{n.active=!1,this.activeTransaction=void 0}if(i){this.restoreCheckpoints(t),this.addRootError(i.code,i.message,!1);return}this.publish(),this.maybeSubmit()}restoreCheckpoints(e){this.items.forEach((t,n)=>{let r=e[n];r&&(t.status=r.status,t.resolution=r.resolution,t.error=r.error,t.validationGeneration=r.validationGeneration+1)}),this.publish()}assertItemMutable(e){if(e&&!e.active||this.activeTransaction&&e!==this.activeTransaction)throw Error(`Interrupt transaction is inactive.`);if(this.resuming)throw Error(`Interrupts cannot be mutated while submitting.`)}assertRootMutable(){if(this.activeTransaction)throw Error(`Interrupt transaction is already active.`);if(this.resuming)throw Error(`Interrupts cannot be mutated while submitting.`)}invalidateRetry(){this.retrySubmission=void 0}submitBatch(e){let t={submission:e};this.activeSubmissionOperation=t,this.resuming=!0,this.retrySubmission=void 0;for(let e of this.items)md(e)&&(e.status=`submitting`);this.publish(),this.performSubmission(t)}async performSubmission(e){try{await this.options.submit(e.submission)}catch(t){if(this.activeSubmissionOperation!==e)return;this.handleSubmissionFailure(t,e.submission)}finally{this.activeSubmissionOperation===e&&(this.activeSubmissionOperation=void 0,this.resuming=!1,this.publish())}}handleSubmissionFailure(e,t){let n=Fd(e);if(n.length===0){let n=e instanceof Error?e.message:String(e);this.addRootError(`transport`,n,!0,`transport`),this.retrySubmission=t;for(let e of this.items)md(e)&&(e.status=`error`);return}let r=n.filter(e=>zd(e,t));r.length!==n.length&&this.addRootError(`protocol`,`Interrupt submission errors did not match the active batch.`,!1);let i=!1,a=!1,o=[];for(let e of r)if((e.code===`stale`||e.code===`expired`||e.code===`conflict`)&&(i=!0),a||=e.retryable,e.scope===`item`){let t=this.items.find(t=>md(t)&&t.descriptor.id===e.interruptId);t&&(t.status=`error`,t.error=$(e))}else o.push($(e));let s=Rd(this.rootErrors,this.submissionRootErrors,o);this.rootErrors=s.rootErrors,this.submissionRootErrors=s.submissionRootErrors;for(let e of this.items)md(e)&&e.status===`submitting`&&(e.status=`error`);this.retrySubmission=a&&!i?t:void 0}addRootError(e,t,n,r=`client`){let i=this.requireHydration();this.rootErrors=Object.freeze([...this.rootErrors,Object.freeze({scope:`batch`,code:e,message:t,source:r,retryable:n,interruptIds:Object.freeze(this.items.filter(md).map(e=>e.descriptor.id)),threadId:i.threadId,interruptedRunId:i.interruptedRunId,generation:i.generation})]),this.publish()}findItem(e){let t=this.items.find(t=>t.descriptor.id===e);if(!t)throw Error(`Unknown interrupt: ${e}`);return t}requireHydration(){if(!this.hydration)throw Error(`InterruptManager is not hydrated.`);return this.hydration}itemError(e,t,n,r){let i=this.requireHydration();return Object.freeze({scope:`item`,interruptId:e,code:t,message:n,...r===void 0?{}:{path:Object.freeze([...r])},source:`client`,retryable:!1,threadId:i.threadId,interruptedRunId:i.interruptedRunId,generation:i.generation})}};function Ud(e,...t){let n=e?.();if(Mu(n))return n;for(let e of t)if(Mu(e))return e}async function Wd(e,t){if(!t)throw new Iu;return await e.prepare(t),e.headers(t)}var Gd=class{clientId;constructor(e){this.clientId=e}clientCreated(e){this.emitEvent(`client:created`,{initialMessageCount:e})}loadingChanged(e){this.emitEvent(`client:loading:changed`,{isLoading:e})}errorChanged(e){this.emitEvent(`client:error:changed`,{error:e})}textUpdated(e,t,n,r){this.emitEvent(`text:chunk:content`,{streamId:e,messageId:t,content:n,...r})}toolCallStateChanged(e,t,n,r,i,a,o){this.emitEvent(`tools:call:updated`,{streamId:e,messageId:t,toolCallId:n,toolName:r,state:i,arguments:a,...o})}thinkingUpdated(e,t,n,r,i){this.emitEvent(`text:chunk:thinking`,{streamId:e,messageId:t,content:n,delta:r,...i})}structuredOutputChanged(e,t,n,r,i){this.emitEvent(e,{streamId:t,messageId:n,...r,...i})}approvalRequested(e,t,n,r,i,a,o){this.emitEvent(`tools:approval:requested`,{streamId:e,messageId:t,toolCallId:n,toolName:r,input:i,approvalId:a,...o})}messageAppended(e,t,n){let r=e.parts.filter(e=>e.type===`text`).map(e=>e.content).join(` `);this.emitEvent(`text:message:created`,{streamId:t,messageId:e.id,role:e.role,content:r,parts:e.parts,...n})}messageSent(e,t){let n=typeof t==`string`?t:t.filter(e=>e.type===`text`).map(e=>e.content).join(``);this.emitEvent(`text:message:created`,{messageId:e,role:`user`,content:n,...Array.isArray(t)&&{parts:t}}),this.emitEvent(`text:message:user`,{messageId:e,role:`user`,content:n,...Array.isArray(t)&&{parts:t}})}reloaded(e){this.emitEvent(`client:reloaded`,{fromMessageIndex:e})}stopped(){this.emitEvent(`client:stopped`)}messagesCleared(){this.emitEvent(`client:messages:cleared`)}toolResultAdded(e,t,n,r,i){this.emitEvent(`tools:result:added`,{toolCallId:e,toolName:t,output:n,state:r,...i})}toolApprovalResponded(e,t,n,r){this.emitEvent(`tools:approval:responded`,{approvalId:e,toolCallId:t,approved:n,...r})}toolFixtureApplied(e){this.emitEvent(`devtools:tool-fixture:applied`,{...e})}},Kd=class extends Gd{emitEvent(){}},qd=class{events;constructor(e){this.events=new Kd(e.clientId)}emitRegistered(){}emitUpdated(){}emitSnapshot(){}emitToolsRegistered(){}emitRunLifecycle(e,t,n,r){}deactivate(){}supersede(){}dispose(){}mountWithTools(e){}notifyToolsChanged(){}setCurrentStreamId(e){}recordStreamId(e){}getCurrentStreamId(){return null}getLastStreamId(){return null}resolveStreamId(){return``}observeChunk(e){}recordMemoryState(e){}beginRun(e,t){}getCurrentRunEventContext(){}getCurrentOrLastRunEventContext(){}findToolCallContext(e){return{toolCallId:e}}async applyFixture(e){}},Jd=e=>new qd(e);function Yd(e){if(Array.isArray(e))return{messages:e};if(e&&Array.isArray(e.messages))return e}function Xd(e){return`toolCallId`in e&&typeof e.toolCallId==`string`?e.toolCallId:void 0}function Zd(e){return`messageId`in e&&typeof e.messageId==`string`?e.messageId:void 0}function Qd(e){return`parentMessageId`in e&&typeof e.parentMessageId==`string`?e.parentMessageId:void 0}var $d=class{adapter;id;applyMessages;applyResume;skipNextPersist=!1;generation=0;queue=Promise.resolve();queuePending=!1;messagesGeneration=0;lastMessages=[];lastResume=null;clearedMessageIds=new Set;clearedRunIds=new Set;ignoredActiveRunIds=new Set;clearedToolCallIds=new Set;currentRunlessRunId=null;constructor(e,t,n,r){this.adapter=e,this.id=t,this.applyMessages=n,this.applyResume=r}writeState(){let e=[...this.lastMessages];if(e.length===0&&!this.lastResume){let e=this.generation;this.runOperation(()=>{if(e===this.generation)return this.adapter.removeItem(this.id)});return}let t=this.generation,n={messages:e,...this.lastResume?{resume:this.lastResume}:{}};this.runOperation(()=>{if(t===this.generation)return this.adapter.setItem(this.id,n)})}readInitial(){try{let e=this.adapter.getItem(this.id);if(e instanceof Promise)return e.then(Yd).catch(()=>void 0);let t=Yd(e);return t&&(this.lastMessages=t.messages,this.lastResume=t.resume??null),t}catch{return}}hydrateAsync(e){if(!(e instanceof Promise))return;let t=this.messagesGeneration;e.then(e=>{!e||this.messagesGeneration!==t||(this.lastResume=e.resume??null,this.lastMessages=e.messages,this.applyMessages(e.messages),e.resume&&this.applyResume&&this.applyResume(e.resume))}).catch(()=>{})}notifyMessagesChanged(e){if(this.messagesGeneration++,this.lastMessages=[...e],this.skipNextPersist){this.skipNextPersist=!1;return}this.writeState()}persistResumeSnapshot(e){this.lastResume=e,!this.skipNextPersist&&this.writeState()}remove(){this.lastMessages=[],this.lastResume=null;let e=++this.generation;this.runOperation(()=>{if(e===this.generation)return this.adapter.removeItem(this.id)})}runOperation(e){if(this.queuePending){let t=this.queue.then(e).catch(()=>{});this.queue=t,t.finally(()=>{this.queue===t&&(this.queuePending=!1)});return}try{let t=e();if(t instanceof Promise){this.queuePending=!0;let e=t.catch(()=>{});this.queue=e,e.finally(()=>{this.queue===e&&(this.queuePending=!1)})}}catch{}}snapshotClear(e){for(let t of e.messages)this.clearedMessageIds.add(t.id);for(let t of e.activeRunIds)this.clearedRunIds.add(t),this.ignoredActiveRunIds.add(t);e.currentRunId&&(this.clearedRunIds.add(e.currentRunId),this.ignoredActiveRunIds.add(e.currentRunId))}beginClear(){this.skipNextPersist=!0}shouldIgnoreChunk(e){let t=Ru(e);if(t&&this.clearedRunIds.has(t))return e.type===`RUN_STARTED`&&(this.ignoredActiveRunIds.add(t),this.currentRunlessRunId=t),this.markIgnoredChunkIds(e),!0;if(t&&this.ignoredActiveRunIds.has(t)||this.isRunlessChunkFromIgnoredRun(e))return this.markIgnoredChunkIds(e),!0;let n=Xd(e);if(n&&this.clearedToolCallIds.has(n))return!0;let r=Qd(e);if(r&&this.clearedMessageIds.has(r))return n&&this.clearedToolCallIds.add(n),!0;let i=Zd(e);return i?!!this.clearedMessageIds.has(i):!1}onRunStarted(e){this.currentRunlessRunId=e}onRunSettled(e){this.ignoredActiveRunIds.delete(e),this.clearedRunIds.delete(e),this.currentRunlessRunId===e&&(this.currentRunlessRunId=this.ignoredActiveRunIds.values().next().value??null)}onSessionRunError(){this.ignoredActiveRunIds.clear(),this.currentRunlessRunId=null}resetIgnored(){this.ignoredActiveRunIds.clear()}takeRunlessRunId(){let e=this.currentRunlessRunId;return e?(this.ignoredActiveRunIds.delete(e),this.clearedRunIds.delete(e),this.currentRunlessRunId=this.ignoredActiveRunIds.values().next().value??null,e):null}markIgnoredChunkIds(e){let t=Zd(e);t&&this.clearedMessageIds.add(t);let n=Xd(e);n&&this.clearedToolCallIds.add(n)}isRunlessChunkFromIgnoredRun(e){return Ru(e)||!this.currentRunlessRunId||!this.ignoredActiveRunIds.has(this.currentRunlessRunId)&&!this.clearedRunIds.has(this.currentRunlessRunId)?!1:e.type===`TEXT_MESSAGE_START`||e.type===`TEXT_MESSAGE_CONTENT`||e.type===`TOOL_CALL_START`||e.type===`TOOL_CALL_ARGS`||e.type===`TOOL_CALL_END`||e.type===`TOOL_CALL_RESULT`||e.type===`MESSAGES_SNAPSHOT`||e.type===`RUN_ERROR`}};function ef(e){return`toolCallId`in e&&typeof e.toolCallId==`string`?e.toolCallId:void 0}function tf(e){return`messageId`in e&&typeof e.messageId==`string`?e.messageId:void 0}function nf(e){return`parentMessageId`in e&&typeof e.parentMessageId==`string`?e.parentMessageId:void 0}var rf=class{clearedMessageIds=new Set;clearedRunIds=new Set;ignoredActiveRunIds=new Set;clearedToolCallIds=new Set;currentRunlessRunId=null;snapshotClear(e){for(let t of e.messages)this.clearedMessageIds.add(t.id);for(let t of e.activeRunIds)this.clearedRunIds.add(t),this.ignoredActiveRunIds.add(t);e.currentRunId&&(this.clearedRunIds.add(e.currentRunId),this.ignoredActiveRunIds.add(e.currentRunId))}shouldIgnoreChunk(e){let t=Ru(e);if(t&&this.clearedRunIds.has(t))return e.type===`RUN_STARTED`&&(this.ignoredActiveRunIds.add(t),this.currentRunlessRunId=t),this.markIgnoredChunkIds(e),!0;if(t&&this.ignoredActiveRunIds.has(t)||this.isRunlessChunkFromIgnoredRun(e))return this.markIgnoredChunkIds(e),!0;let n=ef(e);if(n&&this.clearedToolCallIds.has(n))return!0;let r=nf(e);if(r&&this.clearedMessageIds.has(r))return n&&this.clearedToolCallIds.add(n),!0;let i=tf(e);return!!(i&&this.clearedMessageIds.has(i))}onRunStarted(e){this.currentRunlessRunId=e}onRunSettled(e){this.ignoredActiveRunIds.delete(e),this.clearedRunIds.delete(e),this.currentRunlessRunId===e&&(this.currentRunlessRunId=this.ignoredActiveRunIds.values().next().value??null)}onSessionRunError(){this.ignoredActiveRunIds.clear(),this.currentRunlessRunId=null}resetActiveRuns(){this.ignoredActiveRunIds.clear(),this.currentRunlessRunId=null}takeRunlessRunId(){let e=this.currentRunlessRunId;return e?(this.ignoredActiveRunIds.delete(e),this.clearedRunIds.delete(e),this.currentRunlessRunId=this.ignoredActiveRunIds.values().next().value??null,e):null}markIgnoredChunkIds(e){let t=tf(e);t&&this.clearedMessageIds.add(t);let n=ef(e);n&&this.clearedToolCallIds.add(n)}isRunlessChunkFromIgnoredRun(e){return Ru(e)||!this.currentRunlessRunId||!this.ignoredActiveRunIds.has(this.currentRunlessRunId)&&!this.clearedRunIds.has(this.currentRunlessRunId)?!1:e.type===`TEXT_MESSAGE_START`||e.type===`TEXT_MESSAGE_CONTENT`||e.type===`TOOL_CALL_START`||e.type===`TOOL_CALL_ARGS`||e.type===`TOOL_CALL_END`||e.type===`TOOL_CALL_RESULT`||e.type===`MESSAGES_SNAPSHOT`||e.type===`RUN_ERROR`}};function af(e){let t=new Set;for(let n of e??[]){if(t.has(n.id))throw Error(`Duplicate interrupt definition id: ${n.id}`);t.add(n.id)}}function of(e){let{connection:t,fetcher:n}=e;if(t&&n)throw Error("ChatClient: pass either `connection` or `fetcher`, not both.");if(t)return t;if(n)return fd(n);throw Error("ChatClient: either `connection` or `fetcher` is required.")}function sf(e){let t={whenBusy:`queue`,drain:`fifo`,onOverflow:`reject`};if(!e)return t;if(typeof e==`string`)return{...t,whenBusy:e};if(typeof e==`function`)return{...t,strategy:e};let n=e.maxSize;if(n!==void 0&&(!Number.isInteger(n)||n<0))throw Error(`ChatClient: queue.maxSize must be a non-negative integer`);return{whenBusy:e.whenBusy??`queue`,drain:e.drain??`fifo`,onOverflow:e.onOverflow??`reject`,...n===void 0?{}:{maxSize:n}}}function cf(e){let t=e.at(-1)?.body,n=[];for(let t of e){if(typeof t.content!=`string`)break;n.push(t.content)}if(n.length===e.length)return{content:n.join(`
18
18
  `),...t===void 0?{}:{body:t}};let r=[],i;for(let t of e){if(typeof t.content==`string`){r.push({type:`text`,content:t.content});continue}typeof t.content.content==`string`?r.push({type:`text`,content:t.content.content}):r.push(...t.content.content),i=Mc(i,t.content.metadata)}return{content:{content:r,...i===void 0?{}:{metadata:i}},...t===void 0?{}:{body:t}}}function lf(e){if(!(typeof e!=`object`||!e||Array.isArray(e))&&!(!(`approved`in e)||typeof e.approved!=`boolean`))return e.approved}function uf(e){let t=e;if(typeof t!=`object`||!t||!(`resumeState`in t))return;let n=t.resumeState;if(!(typeof n!=`object`||!n||!(`threadId`in n)||typeof n.threadId!=`string`||n.threadId.length===0||!(`runId`in n)||typeof n.runId!=`string`||n.runId.length===0))return{threadId:n.threadId,runId:n.runId}}var df=2e3,ff=new Set([`TEXT_MESSAGE_START`,`TEXT_MESSAGE_CONTENT`,`TOOL_CALL_START`,`MESSAGES_SNAPSHOT`]),pf=class{processor;connection;uniqueId;threadId;persistor;clearedStreamTracker=new rf;currentRunId=null;lastResume=null;rejoinedRunId=null;interruptManager;activeInterruptSubmission;interruptSubmissionFailure;joinedRunWaiters=new Map;pendingResumeParentRunId=null;pendingResumeThreadId=null;pendingResumeItems=null;activeResumeThreadId=null;activeResumeRunId=null;bodyOption={};forwardedPropsOption={};byok;byokProvider;context=void 0;pendingMessageBody=void 0;queueConfig;messageQueue=[];sendInFlight=!1;messageQueueDraining=!1;stopMessageQueueDrain=!1;deliverClaim=!1;isLoading=!1;isSubscribed=!1;error=void 0;status=`ready`;connectionStatus=`disconnected`;abortController=null;clientToolsRef;devtoolsBridge;events;currentStreamId=null;currentMessageId=null;postStreamActions=[];pendingToolExecutions=new Map;activeClientTools=null;activeContext=void 0;continuationPending=!1;subscriptionAbortController=null;processingResolve=null;errorReportedGeneration=null;streamGeneration=0;continuationSkipped=!1;draining=!1;sessionGenerating=!1;activeRunIds=new Set;disposed=!1;tailing=!1;rejoinRunId;cachesMessages;devtoolsMounted=!1;callbacksRef;constructor(e){af(e.interrupts),this.threadId=e.threadId||``,this.uniqueId=this.threadId;let t=!0;if(e.persistence===!0){if(!e.threadId)throw Error("[TanStack AI] persistence needs a stable `threadId` to key on. Pass a threadId from your app (for example support-42).");t=!1}else if(e.persistence){if(!e.threadId)throw Error("[TanStack AI] persistence needs a stable `threadId` to key on. Pass a threadId from your app (for example support-42).");this.persistor=new $d(e.persistence,e.threadId,e=>this.processor.setMessages(e),e=>this.applyPersistedResume(e))}if(this.bodyOption=e.body||{},this.forwardedPropsOption=e.forwardedProps||{},this.byok=e.byok,this.byokProvider=e.byokProvider,this.context=e.context,this.queueConfig=sf(e.queue),this.connection=ld(of(e)),this.clientToolsRef={current:new Map},e.tools)for(let t of e.tools)this.clientToolsRef.current.set(t.name,t);this.devtoolsBridge=(e.devtoolsBridgeFactory??Jd)(this.buildDevtoolsBridgeOptions(e.devtools)),this.events=this.devtoolsBridge.events,this.callbacksRef={current:{onResponse:e.onResponse||(()=>{}),onChunk:e.onChunk||(()=>{}),onFinish:e.onFinish||(()=>{}),onError:e.onError||(()=>{}),onMessagesChange:e.onMessagesChange||(()=>{}),onLoadingChange:e.onLoadingChange||(()=>{}),onErrorChange:e.onErrorChange||(()=>{}),onStatusChange:e.onStatusChange||(()=>{}),onSubscriptionChange:e.onSubscriptionChange||(()=>{}),onConnectionStatusChange:e.onConnectionStatusChange||(()=>{}),onSessionGeneratingChange:e.onSessionGeneratingChange||(()=>{}),onQueueChange:e.onQueueChange||(()=>{}),onResumeStateChange:e.onResumeStateChange||(()=>{}),onRunIdChange:e.onRunIdChange||(()=>{}),onInterruptStateChange:e.onInterruptStateChange||(()=>{}),onCustomEvent:e.onCustomEvent||(()=>{})}},this.interruptManager=new Hd({...e.tools===void 0?{}:{tools:e.tools},...e.interrupts===void 0?{}:{interrupts:e.interrupts},submit:e=>this.submitInterruptBatch(e),onChange:e=>this.notifyResumeStateChange(e)}),e.initialResumeSnapshot&&this.applyResumeSnapshot(e.initialResumeSnapshot);let n=this.persistor?.readInitial(),r=n instanceof Promise?void 0:n,i=r?r.messages:e.initialMessages,a=null;if(r?.resume){let e=r.resume;Array.isArray(e.pendingInterrupts)&&e.pendingInterrupts.length>0?this.applyResumeSnapshot(e):e.resumeState.runId&&(a=e.resumeState.runId)}if(!a&&e.initialResumeSnapshot){let t=e.initialResumeSnapshot;!(Array.isArray(t.pendingInterrupts)&&t.pendingInterrupts.length>0)&&t.resumeState.runId&&(a=t.resumeState.runId)}this.processor=new Ou({...e.streamProcessor?.chunkStrategy?{chunkStrategy:e.streamProcessor.chunkStrategy}:{},...i?{initialMessages:i}:{},events:{onMessagesChange:e=>{this.persistor?.notifyMessagesChanged(e),this.callbacksRef.current.onMessagesChange(e)},onStreamStart:()=>{this.setStatus(`streaming`);let e=this.processor.getCurrentAssistantMessageId();if(!e)return;let t=this.processor.getMessages().find(t=>t.id===e);t&&(this.currentMessageId=t.id,this.events.messageAppended(t,this.currentStreamId||void 0))},onStreamEnd:e=>{this.callbacksRef.current.onFinish(e),this.setStatus(`ready`),this.resolveProcessing()},onError:e=>{this.reportStreamError(e)},onTextUpdate:(e,t)=>{this.currentStreamId&&this.events.textUpdated(this.currentStreamId,e,t)},onThinkingUpdate:(e,t)=>{this.currentStreamId&&this.events.thinkingUpdated(this.currentStreamId,e,t,void 0)},onStructuredOutputChange:e=>{let t=this.devtoolsBridge.resolveStreamId(),n=e.phase===`start`?`structured-output:started`:e.phase===`complete`?`structured-output:completed`:e.phase===`error`?`structured-output:errored`:`structured-output:updated`;this.currentMessageId=e.messageId,this.events.structuredOutputChanged(n,t,e.messageId,{status:e.status,raw:e.raw,...e.partial===void 0?{}:{partial:e.partial},...e.data===void 0?{}:{data:e.data},...e.reasoning===void 0?{}:{reasoning:e.reasoning},...e.errorMessage===void 0?{}:{errorMessage:e.errorMessage},...e.delta===void 0?{}:{delta:e.delta}})},onToolCallStateChange:(e,t,n,r)=>{let i=this.processor.getMessages().find(t=>t.id===e)?.parts.find(e=>e.type===`tool-call`&&e.id===t)?.name||`unknown`;this.currentStreamId&&this.events.toolCallStateChanged(this.currentStreamId,e,t,i,n,r)},onToolCall:e=>{let t=(this.activeClientTools??this.clientToolsRef.current).get(e.toolName),n=t?.execute;if(n){let r=this.devtoolsBridge.getCurrentRunEventContext(),i=(async()=>{try{let i=this.activeClientTools===null?this.context:this.activeContext,a=await n(e.input,{toolCallId:e.toolCallId,context:i,emitCustomEvent:()=>{}});await this.addToolResultForClientTool({toolCallId:e.toolCallId,tool:e.toolName,output:a,state:`output-available`},t,r)}catch(n){await this.addToolResultForClientTool({toolCallId:e.toolCallId,tool:e.toolName,output:null,state:`output-error`,errorText:n.message},t,r)}finally{this.pendingToolExecutions.delete(e.toolCallId)}})();this.pendingToolExecutions.set(e.toolCallId,i)}},onApprovalRequest:e=>{let t=this.devtoolsBridge.resolveStreamId(),n=this.findMessageIdForToolCall(e.toolCallId)??this.currentMessageId??``;this.events.approvalRequested(t,n,e.toolCallId,e.toolName,e.input,e.approvalId)},onCustomEvent:(e,t,n)=>{e===`memory:state`&&this.devtoolsBridge.recordMemoryState(t),this.callbacksRef.current.onCustomEvent(e,t,n)}}}),this.persistor?.hydrateAsync(n),this.rejoinRunId=a,this.cachesMessages=t}attach(){this.disposed||this.tailing||(this.ensureThreadId(),this.tailing=!0,this.rejoinRunId&&this.maybeRejoinInFlight(this.rejoinRunId),!this.cachesMessages&&this.connection.hydrate&&this.hydrateFromServer())}detach(){this.tailing&&(this.tailing=!1,this.cancelInFlightStream({setReadyStatus:!0}),this.rejoinedRunId=null)}applyResumeSnapshot(e){let t=uf(e);if(t===void 0){this.interruptManager.reset({source:`hydrate`});return}this.lastResume=t;let n=Array.isArray(e.pendingInterrupts)?e.pendingInterrupts:[];if(n.length===0){this.interruptManager.reset({source:`hydrate`});return}let r=this.interruptGeneration(n);this.interruptManager.hydrate({threadId:t.threadId,interruptedRunId:t.runId,generation:r,interrupts:n},`hydrate`)}applyPersistedResume(e){this.applyResumeSnapshot(e);let t=Array.isArray(e.pendingInterrupts)&&e.pendingInterrupts.length>0,n=e.resumeState?.runId;!t&&n&&this.maybeRejoinInFlight(n)}maybeRejoinInFlight(e){this.connection.joinRun&&(this.disposed||!this.tailing||this.rejoinedRunId!==e&&(this.isLoading||this.abortController||(this.rejoinedRunId=e,this.resumeInFlightRun(e))))}hydrateFromServer(){let e=this.connection.hydrate;e&&(this.isLoading||this.abortController||this.disposed||(async()=>{let t;try{t=await e(this.threadId)}catch{return}this.disposed||!this.tailing||this.isLoading||this.abortController||(t.messages.length>0&&this.processor.setMessages(t.messages),t.interrupts&&t.interrupts.pending.length>0?this.applyResumeSnapshot({resumeState:{threadId:this.threadId,runId:t.interrupts.runId},pendingInterrupts:t.interrupts.pending}):t.activeRun?.runId&&this.maybeRejoinInFlight(t.activeRun.runId))})())}mountDevtools(){this.ensureThreadId(),!this.devtoolsMounted&&(this.devtoolsMounted=!0,this.devtoolsBridge.mountWithTools(this.processor.getMessages().length))}ensureThreadId(){return this.threadId||=this.generateUniqueId(`thread`),this.uniqueId=this.threadId,this.threadId}drainIgnoredRunlessChunk(e){if(e.type!==`RUN_ERROR`)return;let t=this.clearedStreamTracker.takeRunlessRunId();t&&(this.activeRunIds.delete(t),this.setSessionGenerating(this.activeRunIds.size>0),this.resolveProcessing())}retireIgnoredClearedTerminalChunk(e){if(e.type!==`RUN_FINISHED`&&e.type!==`RUN_ERROR`)return;let t=Ru(e)??this.clearedStreamTracker.takeRunlessRunId();t&&(this.activeRunIds.delete(t),this.setSessionGenerating(this.activeRunIds.size>0),Ru(e)||this.resolveProcessing())}updateRunLifecycle(e,t){if(e.type===`RUN_STARTED`){let t=Ru(e)??e.runId;this.activeResumeThreadId=`threadId`in e&&typeof e.threadId==`string`?e.threadId:this.activeResumeThreadId,this.activeResumeRunId=t,this.activeRunIds.add(t),this.clearedStreamTracker.onRunStarted(t),this.setSessionGenerating(!0),this.persistor&&this.connection.joinRun&&!this.lastResume&&this.persistResumeSnapshot({threadId:this.activeResumeThreadId??this.threadId,runId:t});return}if(e.type!==`RUN_FINISHED`&&e.type!==`RUN_ERROR`)return;let n=Ru(e);n?(this.activeRunIds.delete(n),this.clearedStreamTracker.onRunSettled(n)):e.type===`RUN_ERROR`&&(this.activeRunIds.clear(),this.clearedStreamTracker.onSessionRunError()),this.setSessionGenerating(this.activeRunIds.size>0),t?.resolveProcessing!==!1&&this.resolveProcessing()}observeInterruptState(e){if(e.type!==`RUN_FINISHED`&&e.type!==`RUN_ERROR`||this.activeInterruptSubmission&&e.type===`RUN_ERROR`)return;let t=Ru(e),n=`threadId`in e&&typeof e.threadId==`string`?e.threadId:this.activeResumeThreadId;if(e.type===`RUN_FINISHED`&&e.outcome?.type===`interrupt`){let r=this.currentRunId??t??this.activeResumeRunId??``;this.lastResume={threadId:n??this.threadId,runId:r},this.interruptManager.hydrate({threadId:this.lastResume.threadId,interruptedRunId:r,generation:this.interruptGeneration(e.outcome.interrupts),interrupts:e.outcome.interrupts},`live`);return}let r=e.type===`RUN_ERROR`&&!t,i=!!(t&&this.lastResume?.runId===t),a=!!(t&&this.currentRunId===t||this.currentRunId&&this.lastResume?.runId===this.currentRunId),o=!!(this.isLoading&&t&&(t===this.activeResumeRunId||t===this.currentRunId)),s=this.isLoading&&e.type===`RUN_FINISHED`&&!t,c=!!(this.activeInterruptSubmission&&this.isLoading&&e.type===`RUN_FINISHED`&&e.outcome?.type!==`interrupt`);if(r||i||a||o||s||c){this.lastResume=null,this.persistor?.persistResumeSnapshot(null),this.interruptManager.reset();return}this.notifyResumeStateChange(`live`)}getResumeState(){return this.lastResume?{...this.lastResume}:null}getCurrentRunId(){return this.currentRunId}setCurrentRunId(e){this.currentRunId!==e&&(this.currentRunId=e,this.callbacksRef.current.onRunIdChange(e))}getInterruptState(){return this.interruptManager.getState()}getInterrupts(){return this.interruptManager.getInterrupts()}getPendingInterrupts(){return this.interruptManager.getInterrupts()}resolveInterrupts(e){if(typeof e==`boolean`){this.interruptManager.resolve(e);return}this.interruptManager.resolve(e)}cancelInterrupts(){this.interruptManager.cancel()}retryInterrupts(){this.interruptManager.retry()}resumeInterruptsUnsafe(e,t){let n=t??this.lastResume;return n?this.isLoading?new Promise((t,r)=>{this.queuePostStreamAction(async()=>{try{t(await this.resumeInterruptsUnsafe(e,n))}catch(e){r(e)}})}):(this.pendingResumeThreadId=n.threadId,this.pendingResumeParentRunId=n.runId,this.pendingResumeItems=[...e],this.streamResponse()):Promise.resolve(!1)}resumeInterrupts(e,t){return this.resumeInterruptsUnsafe(e,t)}async submitInterruptBatch(e){this.activeInterruptSubmission=e,this.interruptSubmissionFailure=void 0;for(let t of e.resolutions){let e=lf(t.payload);if(e===void 0)continue;let n=t.interruptId;this.processor.addToolApprovalResponse(n,e)}let t=await this.resumeInterruptsUnsafe([...e.resolutions],{threadId:e.threadId,runId:e.interruptedRunId}).finally(()=>{this.activeInterruptSubmission=void 0}),n=this.takeInterruptSubmissionFailure();if(n!==void 0)throw{errors:n.errors};if(!t)throw Error(`Interrupt continuation could not be started.`);this.lastResume?.runId===e.interruptedRunId&&(this.lastResume=null,this.interruptManager.reset())}takeInterruptSubmissionFailure(){let e=this.interruptSubmissionFailure;return this.interruptSubmissionFailure=void 0,e}interruptGeneration(e){let t;for(let n of e){let e=n.metadata?.[`tanstack:interruptBinding`];if(typeof e!=`object`||!e||!(`generation`in e)||typeof e.generation!=`number`||!Number.isInteger(e.generation)||e.generation<0||t!==void 0&&t!==e.generation)return 0;t=e.generation}return t??0}generateUniqueId(e){return`${e}-${Date.now()}-${Math.random().toString(36).substring(7)}`}setIsLoading(e){this.isLoading=e,this.callbacksRef.current.onLoadingChange(e),this.events.loadingChanged(e)}setStatus(e){this.status=e,this.callbacksRef.current.onStatusChange(e),this.devtoolsBridge.emitSnapshot()}setIsSubscribed(e){this.isSubscribed=e,this.callbacksRef.current.onSubscriptionChange(e),this.devtoolsBridge.emitSnapshot()}setConnectionStatus(e){this.connectionStatus=e,this.callbacksRef.current.onConnectionStatusChange(e),this.devtoolsBridge.emitSnapshot()}setSessionGenerating(e){this.sessionGenerating!==e&&(this.sessionGenerating=e,this.callbacksRef.current.onSessionGeneratingChange(e),this.devtoolsBridge.emitSnapshot())}notifyResumeStateChange(e){let t=this.getResumeState(),n=this.interruptManager.getState();this.persistResumeSnapshot(t),this.callbacksRef.current.onResumeStateChange(t,n.interrupts),this.callbacksRef.current.onInterruptStateChange(n,{source:e})}persistResumeSnapshot(e){if(!this.persistor)return;if(!e){this.persistor.persistResumeSnapshot(null);return}let t=this.interruptManager.getDescriptors();this.persistor.persistResumeSnapshot({resumeState:e,...t.length>0?{pendingInterrupts:[...t]}:{}})}resetSessionGenerating(e){this.activeRunIds.clear(),e?.preserveClearedStreamTracking||this.clearedStreamTracker.resetActiveRuns(),this.setSessionGenerating(!1)}setError(e){this.error=e,this.callbacksRef.current.onErrorChange(e),this.events.errorChanged(e?.message||null)}buildDevtoolsBridgeOptions(e){let t=this;return{get hookId(){return t.uniqueId},get clientId(){return t.uniqueId},get threadId(){return t.threadId},metadata:{hookName:e?.hookName??`useChat`,outputKind:e?.outputKind??`chat`,...e?.framework?{framework:e.framework}:{},...e?.name?{name:e.name}:{}},getSnapshot:()=>this.getDevtoolsSnapshot(),getTools:()=>this.clientToolsRef.current.values(),getMessages:()=>this.processor.getMessages(),setMessages:e=>{this.processor.setMessages(e)},addToolResult:(e,t,n)=>{this.processor.addToolResult(e,t,n)},generateId:e=>this.generateUniqueId(e)}}getDevtoolsSnapshot(){return{messages:this.processor.getMessages(),status:this.status,isLoading:this.isLoading,isSubscribed:this.isSubscribed,connectionStatus:this.connectionStatus,sessionGenerating:this.sessionGenerating,activeRunIds:Array.from(this.activeRunIds),queue:this.getQueue(),...this.error?{error:this.error.message}:{}}}findMessageIdForToolCall(e){let t=this.processor.getMessages();for(let n of t)if(n.parts.find(t=>t.type===`tool-call`&&t.id===e))return n.id}abortSubscriptionLoop(){this.subscriptionAbortController?.abort(),this.subscriptionAbortController=null}resolveProcessing(){this.processingResolve?.(),this.processingResolve=null}cancelInFlightStream(e){this.abortController?.abort(),this.abortController=null,e?.abortSubscription&&this.abortSubscriptionLoop(),this.resolveProcessing(),this.setIsLoading(!1),this.deliverClaim=!1,e?.setReadyStatus&&this.setStatus(`ready`)}reportStreamError(e){let t=this.errorReportedGeneration===this.streamGeneration;this.setError(e),(this.isLoading||this.status===`submitted`||this.status===`streaming`)&&this.setStatus(`error`),t||(this.errorReportedGeneration=this.streamGeneration,this.callbacksRef.current.onError(e))}startSubscription(){this.subscriptionAbortController=new AbortController;let e=this.subscriptionAbortController.signal;this.consumeSubscription(e).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&(this.setConnectionStatus(`error`),this.resetSessionGenerating(),this.setIsSubscribed(!1),this.reportStreamError(e)),this.resolveProcessing()}).finally(()=>{this.subscriptionAbortController?.signal===e&&(this.subscriptionAbortController=null,!e.aborted&&this.isSubscribed&&(this.setIsSubscribed(!1),this.connectionStatus!==`error`&&this.setConnectionStatus(`disconnected`)))})}async consumeSubscription(e){let t=this.connection.subscribe(e);for await(let n of t){if(e.aborted)break;await this.processIncomingChunk(n)}}resumeInFlightRun(e){let t=this.connection.joinRun;if(!t)return;let n=new AbortController;this.abortController=n,this.setCurrentRunId(e),this.lastResume={threadId:this.threadId,runId:e},this.setIsLoading(!0),this.setStatus(`streaming`),(async()=>{let r=!1,i=!1,a=!1,o=setTimeout(()=>{i||n.abort()},df);try{for await(let a of t(e,n.signal)){if(n.signal.aborted)break;i||(i=!0,clearTimeout(o)),!r&&ff.has(a.type)&&(r=!0,this.dropTrailingInFlightAssistant()),await this.processIncomingChunk(a,{defer:!1})}this.pendingToolExecutions.size>0&&await Promise.all(this.pendingToolExecutions.values())}catch(e){let t=e instanceof Error&&(e.name===`AbortError`||e.name===`TimeoutError`);!i&&!t&&(a=!0),i&&!t&&this.reportStreamError(e instanceof Error?e:Error(String(e)))}finally{clearTimeout(o),!i&&a&&this.tailing&&!this.disposed&&(this.lastResume=null,this.persistor?.persistResumeSnapshot(null)),this.abortController===n&&(this.abortController=null,this.setIsLoading(!1),this.status===`streaming`&&this.setStatus(`ready`),await this.drainPostStreamActions())}})()}dropTrailingInFlightAssistant(){let e=this.processor.getMessages(),t=e[e.length-1];t&&t.role===`assistant`&&this.processor.setMessages(e.slice(0,-1))}async processIncomingChunk(e,t){if(e=Ll(e),e.type===`RUN_ERROR`&&this.isActiveInterruptSubmissionFailure(e)){let t=Q(e)?.interruptErrors;this.interruptSubmissionFailure={errors:Array.isArray(t)?t:[]}}if(this.connectionStatus===`connecting`&&this.setConnectionStatus(`connected`),this.clearedStreamTracker.shouldIgnoreChunk(e)){(e.type===`RUN_FINISHED`||e.type===`RUN_ERROR`)&&(Ru(e)?this.updateRunLifecycle(e,{resolveProcessing:!1}):this.drainIgnoredRunlessChunk(e),this.retireIgnoredClearedTerminalChunk(e),this.resolveJoinedRun(e));return}this.callbacksRef.current.onChunk(e),this.devtoolsBridge.observeChunk(e),this.processor.processChunk(e),this.updateRunLifecycle(e),this.observeInterruptState(e),t?.defer!==!1&&(typeof document>`u`||!document.hidden)&&await new Promise(e=>setTimeout(e,0)),this.resolveJoinedRun(e)}isActiveInterruptSubmissionFailure(e){let t=this.activeInterruptSubmission,n=Q(e)?.interruptErrors;if(!t||!Array.isArray(n)||n.length===0)return!1;let r=Ru(e);return r!==void 0&&r!==this.currentRunId||typeof e.threadId==`string`&&e.threadId!==t.threadId?!1:n.every(e=>typeof e!=`object`||!e||typeof e.threadId!=`string`||typeof e.interruptedRunId!=`string`||typeof e.generation!=`number`?!1:e.threadId===t.threadId&&e.interruptedRunId===t.interruptedRunId&&e.generation===t.generation)}resolveJoinedRun(e){if(e.type!==`RUN_FINISHED`&&e.type!==`RUN_ERROR`)return;let t=Ru(e);if(t===void 0)return;let n=this.joinedRunWaiters.get(t);n!==void 0&&(this.joinedRunWaiters.delete(t),n())}ensureSubscription(){if(!this.isSubscribed){this.subscribe();return}(!this.subscriptionAbortController||this.subscriptionAbortController.signal.aborted)&&this.subscribe({restart:!0})}waitForProcessing(){return this.resolveProcessing(),new Promise(e=>{this.processingResolve=e})}async sendMessage(e,t,n){if(this.mountDevtools(),typeof e==`string`&&!e.trim())return;if(this.hasBlockingInterrupts())throw Error(`ChatClient: cannot send normal input while pending interrupts exist. Use resumeInterrupts() instead.`);let r={...t,...n?.body};if(this.isSendBusy()){let{action:t,id:i}=this.decideWhenBusy(e,n);if(t===`drop`)return;if(t===`queue`){this.enqueueMessage(e,r,i);return}this.stopMessageQueueDrain=!0,this.sendInFlight=!0,this.cancelInFlightStream({setReadyStatus:!0}),this.resetSessionGenerating()}else this.sendInFlight=!0;try{await this.deliverMessage(e,r)}finally{this.sendInFlight=!1}}hasPendingInterrupts(){return this.interruptManager.getDescriptors().length>0}hasBlockingInterrupts(){return this.activeInterruptSubmission!==void 0||this.hasPendingInterrupts()}isSendBusy(){return this.isLoading||this.sendInFlight||this.messageQueueDraining}resolveBusyReason(){return this.isLoading?`streaming`:this.messageQueueDraining?`draining`:`sendInFlight`}async deliverMessage(e,t){if(this.isLoading||this.deliverClaim)return!1;this.deliverClaim=!0;try{let n=this.normalizeMessageInput(e);this.pendingMessageBody=t;let r=this.processor.addUserMessage(n.content,n.id,n.metadata);return this.events.messageSent(r.id,n.content),await this.streamResponse()}finally{this.deliverClaim=!1}}decideWhenBusy(e,t){let n=this.generateUniqueId(`queued`);if(t?.whenBusy)return{action:t.whenBusy,id:n};let{strategy:r,whenBusy:i}=this.queueConfig;if(r){let{action:t}=r({pending:{id:n,content:e,createdAt:Date.now()},busyReason:this.resolveBusyReason(),queued:this.getQueue()});return{action:t,id:n}}return{action:i,id:n}}enqueueMessage(e,t,n){let{maxSize:r,onOverflow:i}=this.queueConfig;if(r!==void 0&&this.messageQueue.length>=r){if(i===`reject`||r===0)return;this.messageQueue.shift()}this.messageQueue.push({id:n??this.generateUniqueId(`queued`),content:e,createdAt:Date.now(),...t===void 0?{}:{body:t}}),this.emitQueueChange()}normalizeMessageInput(e){return typeof e==`string`?{content:e.trim()}:{content:e.content,id:e.id,...e.metadata===void 0?{}:{metadata:e.metadata}}}async append(e){if(this.mountDevtools(),this.hasBlockingInterrupts())throw Error(`ChatClient: cannot append normal input while pending interrupts exist. Use resumeInterrupts() instead.`);let t=au(e,ou);if(t.role===`system`)return;let n=t;this.events.messageAppended(n);let r=this.processor.getMessages();if(this.processor.setMessages([...r,n]),this.devtoolsBridge.emitSnapshot(),this.isLoading){this.queuePostStreamAction(async()=>{await this.streamResponse()});return}await this.streamResponse()}async streamResponse(){if(this.isLoading)return!1;let e=++this.streamGeneration,t=this.pendingResumeThreadId,n=this.pendingResumeParentRunId,r=this.pendingResumeItems;this.pendingResumeThreadId=null,this.pendingResumeParentRunId=null,this.pendingResumeItems=null;let i=`run-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;this.setCurrentRunId(i),this.activeResumeThreadId=t??this.threadId,this.activeResumeRunId=i,this.setIsLoading(!0),this.deliverClaim=!1,this.setStatus(`submitted`),this.setError(void 0),this.errorReportedGeneration=null,this.abortController=new AbortController;let a=this.abortController.signal;this.pendingToolExecutions.clear();let o=!1,s=null,c=!1;try{let l=this.processor.getMessages(),u=new Map(this.clientToolsRef.current),d=this.context;if(await this.callbacksRef.current.onResponse(),a.aborted)return!1;let f={...this.bodyOption,...this.forwardedPropsOption,...this.pendingMessageBody};this.pendingMessageBody=void 0,this.currentStreamId=this.generateUniqueId(`stream`),this.devtoolsBridge.setCurrentStreamId(this.currentStreamId),this.currentMessageId=null,this.activeClientTools=u,this.activeContext=d,this.processor.prepareAssistantMessage(),this.ensureSubscription();let p=this.waitForProcessing(),m;if(this.byok){let e=Ud(this.byokProvider,f.provider);m=await Wd(this.byok,e)}let h={threadId:t??this.threadId,runId:i,...n===null?{}:{parentRunId:n},clientTools:Array.from(u.values()).map(e=>({name:e.name,description:e.description,parameters:e.inputSchema?Zc(e.inputSchema):{type:`object`}})),forwardedProps:{...f},...r?{resume:r}:{},...m?{headers:m}:{}};if(this.devtoolsBridge.beginRun(h.runId,h.threadId),s=h.runId,this.devtoolsBridge.emitRunLifecycle(`run:created`,h.runId,`created`),this.devtoolsBridge.emitRunLifecycle(`run:started`,h.runId,`started`),this.devtoolsBridge.emitSnapshot(),await this.connection.send(l,f,a,h),e!==this.streamGeneration||a.aborted||(await p,e!==this.streamGeneration))return!1;if(this.status===`error`)return s&&(this.devtoolsBridge.emitRunLifecycle(`run:errored`,s,`errored`,this.error?{error:this.error.message}:{}),c=!0),!1;this.pendingToolExecutions.size>0&&await Promise.all(this.pendingToolExecutions.values()),this.processor.finalizeStream(),o=!0}catch(t){let n=t instanceof Error?t:Error(String(t));if(n.name===`AbortError`)return s&&(this.devtoolsBridge.emitRunLifecycle(`run:cancelled`,s,`cancelled`),c=!0),!1;if(n instanceof Pu&&this.byok?.request(n.provider,`missing`),n instanceof Fu&&n.reason===`locked`&&this.byok?.request(n.provider,`locked`),e===this.streamGeneration&&(this.reportStreamError(n),s&&(this.devtoolsBridge.emitRunLifecycle(`run:errored`,s,`errored`,{error:n.message}),c=!0)),e===this.streamGeneration&&(n instanceof Pu||n instanceof Fu||n instanceof Iu))throw n}finally{e===this.streamGeneration&&(this.currentStreamId=null,this.devtoolsBridge.setCurrentStreamId(null),this.currentMessageId=null,this.setCurrentRunId(null),this.activeClientTools=null,this.activeContext=void 0,this.abortController=null,this.setIsLoading(!1),this.pendingMessageBody=void 0,s&&!c&&(o?this.devtoolsBridge.emitRunLifecycle(`run:completed`,s,`completed`):a.aborted&&this.devtoolsBridge.emitRunLifecycle(`run:cancelled`,s,`cancelled`)),await this.drainPostStreamActions(),o?(this.status!==`ready`&&this.setStatus(`ready`),this.messageQueueDraining||await this.drainQueue()):this.flushQueue())}return o}subscribe(e){let t=e?.restart===!0;this.isSubscribed&&!t||(this.isSubscribed&&t&&this.abortSubscriptionLoop(),this.setIsSubscribed(!0),this.setConnectionStatus(`connecting`),this.startSubscription())}unsubscribe(){this.cancelInFlightStream({setReadyStatus:!0,abortSubscription:!0}),this.discardPendingSends(),this.resetSessionGenerating(),this.setIsSubscribed(!1),this.setConnectionStatus(`disconnected`)}async reload(){let e=this.processor.getMessages();if(e.length===0)return;let t=e.findLastIndex(e=>e.role===`user`);t!==-1&&(this.isLoading&&this.cancelInFlightStream(),this.discardPendingSends(),this.events.reloaded(t),this.processor.removeMessagesAfter(t),this.devtoolsBridge.emitSnapshot(),await this.streamResponse())}stop(){let e=this.abortController!==null;this.cancelInFlightStream({setReadyStatus:!0}),this.discardPendingSends(),e&&this.resetSessionGenerating(),this.events.stopped()}clear(){let e=this.abortController!==null;this.clearedStreamTracker.snapshotClear({messages:this.processor.getMessages(),activeRunIds:this.activeRunIds,currentRunId:this.currentRunId}),this.isLoading||e?(this.cancelInFlightStream({setReadyStatus:!0}),this.resetSessionGenerating({preserveClearedStreamTracking:!0})):this.activeRunIds.size>0&&this.resetSessionGenerating({preserveClearedStreamTracking:!0}),this.persistor?.beginClear(),this.processor.clearMessages(),this.discardPendingSends(),this.persistor?.remove(),this.lastResume=null,this.interruptManager.reset(),this.pendingResumeThreadId=null,this.pendingResumeParentRunId=null,this.pendingResumeItems=null,this.setError(void 0),this.events.messagesCleared()}async addToolResult(e){let t=this.clientToolsRef.current.get(e.tool);await this.addToolResultForClientTool(e,t)}async addToolResultForClientTool(e,t,n){if(t&&e.state!==`output-error`)try{e={...e,output:this.validateClientToolOutput(t,e.output)}}catch(t){e={...e,output:null,state:`output-error`,errorText:t.message}}if(this.events.toolResultAdded(e.toolCallId,e.tool,e.output,e.state||`output-available`,n),this.processor.addToolResult(e.toolCallId,e.output,e.state===`output-error`?e.errorText||`Tool execution failed`:void 0),this.devtoolsBridge.emitSnapshot(),!this.interruptManager.resolveClientToolOutput(e.toolCallId,e.state===`output-error`?{error:e.errorText||`Tool execution failed`}:e.output)){if(this.isLoading){this.queuePostStreamAction(()=>this.checkForContinuation());return}await this.checkForContinuation()}}validateClientToolOutput(e,t){return e.outputSchema&&qc(e.outputSchema)?$c(e.outputSchema,t):t}async addToolApprovalResponse(e){if(this.processor.addToolApprovalResponse(e.id,e.approved),this.devtoolsBridge.emitSnapshot(),this.interruptManager.resolveToolApprovalDecision(e.id,e.approved))return;let t=this.processor.getMessages(),n;for(let r of t){let t=r.parts.find(t=>t.type===`tool-call`&&t.approval?.id===e.id);if(t){n=t.id;break}}if(n&&this.events.toolApprovalResponded(e.id,n,e.approved),this.processor.addToolApprovalResponse(e.id,e.approved),this.devtoolsBridge.emitSnapshot(),this.isLoading){this.queuePostStreamAction(()=>this.checkForContinuation());return}await this.checkForContinuation()}queuePostStreamAction(e){this.postStreamActions.push(e)}async drainPostStreamActions(){if(!this.draining){this.draining=!0;try{let e;for(;(e=this.postStreamActions.shift())!==void 0;)await e()}finally{this.draining=!1}}}async checkForContinuation(){if(!this.hasPendingInterrupts()){if(this.continuationPending||this.isLoading){this.continuationSkipped=!0;return}if(this.shouldAutoSend()){this.continuationPending=!0,this.continuationSkipped=!1;let e=!1;try{e=await this.streamResponse()}finally{this.continuationPending=!1}this.continuationSkipped&&e&&(this.continuationSkipped=!1,await this.checkForContinuation())}}}shouldAutoSend(){if(this.lastResume||this.activeInterruptSubmission&&this.hasPendingInterrupts()||this.interruptManager.getInterrupts().length>0)return!1;let e=this.processor.getMessages().findLast(e=>e.role===`assistant`);return!e||!e.parts.some(e=>e.type===`tool-call`)?!1:this.processor.areAllToolsComplete()}getMessages(){return this.processor.getMessages()}shouldAbortMessageQueueDrain(){return this.isLoading||this.stopMessageQueueDrain}async drainQueue(){if(!(this.messageQueueDraining||this.isLoading||this.messageQueue.length===0)){this.messageQueueDraining=!0,this.stopMessageQueueDrain=!1;try{if(this.queueConfig.drain===`batch`){for(;this.messageQueue.length>0;){if(this.shouldAbortMessageQueueDrain())return;let e=this.messageQueue.splice(0);this.emitQueueChange();let t=cf(e);if(!await this.deliverMessage(t.content,t.body)||this.shouldAbortMessageQueueDrain())return}return}for(;this.messageQueue.length>0;){if(this.shouldAbortMessageQueueDrain())return;let e=this.messageQueue.shift();if(e===void 0||(this.emitQueueChange(),!await this.deliverMessage(e.content,e.body)||this.shouldAbortMessageQueueDrain()))return}}finally{this.messageQueueDraining=!1,this.stopMessageQueueDrain=!1}}}discardPendingSends(){this.sendInFlight=!1,this.flushQueue()}getQueue(){return this.messageQueue.map(({id:e,content:t,createdAt:n})=>({id:e,content:t,createdAt:n}))}emitQueueChange(){this.callbacksRef.current.onQueueChange(this.getQueue()),this.devtoolsBridge.emitSnapshot()}cancelQueued(e){let t=this.messageQueue.findIndex(t=>t.id===e);t!==-1&&(this.messageQueue.splice(t,1),this.emitQueueChange())}flushQueue(){this.messageQueue.length!==0&&(this.messageQueue=[],this.emitQueueChange())}getIsLoading(){return this.isLoading}getStatus(){return this.status}getIsSubscribed(){return this.isSubscribed}getConnectionStatus(){return this.connectionStatus}getSessionGenerating(){return this.sessionGenerating}getError(){return this.error}setMessagesManually(e){this.processor.setMessages(e),this.devtoolsBridge.emitSnapshot()}updateOptions(e){if(e.connection!==void 0||e.fetcher!==void 0){let t=this.isSubscribed;this.isLoading?this.cancelInFlightStream({setReadyStatus:!0,abortSubscription:!0}):t&&this.abortSubscriptionLoop(),this.resetSessionGenerating(),this.setIsSubscribed(!1),this.setConnectionStatus(`disconnected`),this.connection=ld(of({connection:e.connection,fetcher:e.fetcher})),t&&this.subscribe()}if(e.body!==void 0&&(this.bodyOption=e.body),e.forwardedProps!==void 0&&(this.forwardedPropsOption=e.forwardedProps),e.byok!==void 0&&(this.byok=e.byok),e.byokProvider!==void 0&&(this.byokProvider=e.byokProvider),`context`in e&&(this.context=e.context),e.tools!==void 0){this.interruptManager.updateTools(e.tools),this.clientToolsRef.current=new Map;for(let t of e.tools)this.clientToolsRef.current.set(t.name,t);this.devtoolsBridge.notifyToolsChanged()}e.queue!==void 0&&(this.queueConfig=sf(e.queue)),e.onResponse!==void 0&&(this.callbacksRef.current.onResponse=e.onResponse),e.onChunk!==void 0&&(this.callbacksRef.current.onChunk=e.onChunk),e.onFinish!==void 0&&(this.callbacksRef.current.onFinish=e.onFinish),e.onError!==void 0&&(this.callbacksRef.current.onError=e.onError),e.onSubscriptionChange!==void 0&&(this.callbacksRef.current.onSubscriptionChange=e.onSubscriptionChange),e.onConnectionStatusChange!==void 0&&(this.callbacksRef.current.onConnectionStatusChange=e.onConnectionStatusChange),e.onSessionGeneratingChange!==void 0&&(this.callbacksRef.current.onSessionGeneratingChange=e.onSessionGeneratingChange),e.onQueueChange!==void 0&&(this.callbacksRef.current.onQueueChange=e.onQueueChange),e.onResumeStateChange!==void 0&&(this.callbacksRef.current.onResumeStateChange=e.onResumeStateChange),e.onRunIdChange!==void 0&&(this.callbacksRef.current.onRunIdChange=e.onRunIdChange),e.onInterruptStateChange!==void 0&&(this.callbacksRef.current.onInterruptStateChange=e.onInterruptStateChange),e.onCustomEvent!==void 0&&(this.callbacksRef.current.onCustomEvent=e.onCustomEvent)}dispose(){this.disposed=!0,this.unsubscribe(),this.devtoolsBridge.dispose(),this.devtoolsMounted=!1}};function mf(e){if(!e)return{type:`object`};if(!(`~standard`in e))return e;try{return Zc(e)}catch{return{type:`object`}}}async function hf(e,t){if(!e||!(`~standard`in e))return t;let n=await e[`~standard`].validate(t);return n.issues?null:n.value??{}}function gf(e,t,n,r){return[...Object.keys(e).length>0?[_f(e,n)]:[],vf(),...yf(t,r)]}function _f(e,t){return su({name:`render_widget`,description:`Render one of the host application's own UI widgets inline in the conversation. The widget appears in the transcript at the point of the call, so prefer it over describing the same information in text. Available widgets:
19
19
  `+Object.entries(e).map(([e,{description:t,parameters:n}])=>`- ${e}: ${t} Props schema: ${JSON.stringify(mf(n))}`).join(`
20
- `),inputSchema:{type:`object`,properties:{widget:{type:`string`,enum:Object.keys(e),description:`Name of the widget to render.`},props:{type:`object`,description:`Props for the widget, matching its props schema.`}},required:[`widget`]}}).client((e,n)=>t(e,n?.toolCallId??``))}function vf(){return su({name:Mt,description:`Ask the user a short structured questionnaire rendered inline in the chat. Use it when the next step genuinely depends on their choices instead of asking in prose. The call stays pending until the user submits; their answers arrive as the tool output. Skipped optional questions come back with an empty answers array. An output with skipped: true means the user dismissed the questionnaire by continuing the conversation instead — do not re-ask; address their next message.`,inputSchema:{type:`object`,properties:{items:{type:`array`,minItems:1,description:`Questions shown one at a time, in order.`,items:{type:`object`,properties:{name:{type:`string`,description:`Unique key identifying the question.`},title:{type:`string`,description:`The question itself.`},description:{type:`string`,description:`Optional helper text.`},required:{type:`boolean`,description:`Whether an answer is mandatory.`},multiple:{type:`boolean`,description:`Whether several choices may be selected.`},choices:{type:`array`,minItems:1,items:{type:`object`,properties:{value:{type:`string`},label:{type:`string`},description:{type:`string`}},required:[`value`,`label`]}},input:{type:`object`,description:`Optional free-form alternative to the fixed choices.`,properties:{label:{type:`string`},placeholder:{type:`string`}},required:[`label`,`placeholder`]}},required:[`name`,`title`,`choices`]}}},required:[`items`]}}).client()}function yf(e,t){return Object.entries(e).map(([e,n])=>su({name:e,description:n.description,inputSchema:mf(n.parameters),...n.metadata?{metadata:n.metadata}:{}}).client(async r=>{t?.(`tool`,`executing host tool "${e}"`,{input:r});let i=await hf(n.parameters,r??{});if(i==null)throw t?.(`error`,`input for host tool "${e}" failed schema validation`,{input:r}),Error(`Input for tool "${e}" failed schema validation`);try{let r=await n.execute(i);return t?.(`tool`,`host tool "${e}" returned`,{output:r}),r}catch(n){throw t?.(`error`,`host tool "${e}" threw`,{error:n}),n}}))}function bf(e,t){return e.length===t.length&&e.every((e,n)=>e.name===t[n]?.name&&e.title===t[n]?.title)}function xf(e,t=!1){let n={...e},r=Ae(n.debug),a=new Set,o={messages:[],status:`ready`,error:void 0,auth:{status:`loading`},capabilities:{attachments:!0},agentTools:[],sandboxStatus:void 0,sandbox:{files:[],commands:[]}},s=e=>{o={...o,...e};for(let e of a)e()},c=E({apiUrl:n.apiUrl,scope:`tenant`,fetchAstralBeamToken:n.fetchAstralBeamToken??{url:`/api/astralbeam/token`}}),l,u,d,f=!1,p=0,m,h=async()=>{let e=++p;try{let t=await A(c);if(e!==p)return;let i=await Se(n.agentId?{agentId:n.agentId}:{},{apiUrl:c.apiUrl,astralBeamToken:t,signal:c.session.abortController.signal,fetchClient:(e,t)=>ge({...c,input:e,init:t})});if(e!==p)return;let a=i.capabilities?.attachments!==!1;s({capabilities:{attachments:a}}),r?.(`mount`,`agent capabilities resolved`,{attachments:a})}catch(e){r?.(`error`,`agent capabilities could not be resolved; keeping the defaults`,e)}},g=new Map,v=()=>{for(let e of g.values())e();g.clear()},y=async(e,t)=>{let r=n.widgets??{};if(!Object.hasOwn(r,e.widget))throw Error(`Unknown widget "${e.widget}"`);let i=r[e.widget],a=await hf(i?.parameters,e.props??{});if(a==null)throw Error(`Props for widget "${e.widget}" failed validation`);g.get(t)?.(),g.delete(t);let o,s=n.onRenderWidget?.({widget:e.widget,props:a,toolCallId:t,release:()=>{g.get(t)===o&&g.delete(t)}});return s&&(o=s,g.set(t,s)),{widget:e.widget,rendered:n.onRenderWidget!==void 0}},b=()=>gf(n.widgets??{},n.tools??{},y,r),x=()=>{let e=b(),t=e.map(e=>{let t=e.metadata?.title;return{name:e.name,title:typeof t==`string`&&t.length>0?t:void 0}});return bf(o.agentTools,t)||s({agentTools:t}),e},S=()=>({...n.agentId?{agentId:n.agentId}:{},...n.debug?{debug:!0}:{}}),C=dd(()=>i(O(),c.apiUrl),async()=>{let e=d,t=await A(c);if(e!==void 0&&e!==d)throw new DOMException(`Identity changed`,`AbortError`);return{fetchClient:(e,n)=>Te(O(),{...n,apiUrl:c.apiUrl,astralBeamToken:t,fetchClient:(e,t)=>ge({...c,input:e,init:t})})}}),w=C.connect;C.connect=async function*(...e){try{yield*w(...e)}catch(e){throw e instanceof Error&&_(e.cause)?e.cause:e}};let T=new pf({connection:C,tools:x(),forwardedProps:S(),onMessagesChange:e=>{s({messages:e,sandbox:_i(e),error:T.getError()})},onStatusChange:e=>s({status:e,error:T.getError()}),onCustomEvent:(e,t)=>{let n=t?.state;if(e===`astralbeam.sandbox.status`&&(n===`starting`||n===`ready`||n===`error`)){r?.(`sandbox`,`sandbox ${n}`),s({sandboxStatus:n});return}r?.(`stream`,`custom event "${e}"`,t)},onChunk:e=>n.streamCallbacks?.onChunk?.(e),onResponse:e=>n.streamCallbacks?.onResponse?.(e),onFinish:e=>n.streamCallbacks?.onFinish?.(e),onError:e=>n.streamCallbacks?.onError?.(e)}),D=()=>{for(let e of o.messages)for(let t of e.parts)t.type!==`tool-call`||Lt(t)||(t.name===`ask_questionnaire`?(r?.(`questionnaire`,`skipping pending questionnaire before send`,{id:t.id}),T.addToolResult({toolCallId:t.id,tool:t.name,output:{answers:[],skipped:!0}})):(r?.(`tool`,`settling unimplemented tool call "${t.name}" as error`,{id:t.id}),T.addToolResult({toolCallId:t.id,tool:t.name,output:null,state:`output-error`,errorText:`The application hosting this chat has no implementation for "${t.name}"`})))},k=()=>{let e=H(c);if(e.status===`ready`){let t=me(e.currentUser);d!==void 0&&d!==t&&(T.stop(),T.clear(),v(),s({messages:[],sandbox:{files:[],commands:[]},sandboxStatus:void 0})),d=t,m!==t&&(m=t,h())}s({auth:e})},j=()=>{f||(f=!0,u=xe(c,k),k(),l=oe(c))};return t||j(),{start:j,getState:()=>o,subscribe:e=>(a.add(e),()=>a.delete(e)),updateOptions:e=>{let t=n.agentId,i=n.apiUrl;n={...n,...e},r=Ae(n.debug),M(c,{apiUrl:n.apiUrl,fetchAstralBeamToken:n.fetchAstralBeamToken??{url:`/api/astralbeam/token`}}),c.debug=r,T.updateOptions({tools:x(),forwardedProps:S()}),f&&(n.agentId!==t||n.apiUrl!==i)&&h()},sendMessage:e=>(D(),T.sendMessage(e)),addToolResult:e=>T.addToolResult(e),stop:()=>T.stop(),retryAuthentication:()=>{A({...c,force:!0}).catch(()=>void 0)},reload:()=>T.reload(),reset:()=>{r?.(`status`,`conversation reset`),T.clear(),v(),s({messages:[],sandbox:{files:[],commands:[]},sandboxStatus:void 0,error:void 0})},dispose:()=>{v(),T.stop(),p++,m=void 0,l?.(),u?.(),le(c),f=!1,queueMicrotask(()=>{f||T.dispose()}),a.clear()}}}const Sf=[`header`,`empty`,`composerActions`];function Cf(e){return`${Vt}${e===`composerActions`?`composer-actions`:e}`}function wf(e,t,n){let[r,i]=(0,q.useState)(new Set),a=(0,q.useRef)(new Map);return(0,q.useEffect)(()=>{for(let r of Sf){let i=e?.[r],o=a.current.get(r);if(o?.renderer===i||(o&&(o.cleanup?.(),o.container.remove(),a.current.delete(r),n?.(`mount`,`host slot "${r}" disposed`)),!i))continue;let s=document.createElement(`div`);s.slot=Cf(r),t.append(s);let c=i(s);a.current.set(r,{renderer:i,container:s,cleanup:c??void 0}),n?.(`mount`,`host slot "${r}" rendered`)}i(e=>{let t=new Set(a.current.keys());return t.size===e.size&&[...t].every(t=>e.has(t))?e:t})},[e,t,n]),(0,q.useEffect)(()=>()=>{for(let e of a.current.values())e.cleanup?.(),e.container.remove();a.current.clear()},[]),r}function Tf(e,t,n){let[r,i]=(0,q.useState)(new Map),a=(0,q.useRef)(new Map),o=(0,q.useCallback)(e=>{let t=[];for(let[n,r]of a.current)e(r)&&(r.cleanup?.(),r.container.remove(),r.release(),a.current.delete(n),t.push(Jt(n)));return t},[]),s=(0,q.useCallback)(e=>{let t=o(e);return t.length>0&&i(e=>{let n=new Map(e);for(let e of t)n.delete(e);return n}),t.length},[o]),c=(0,q.useRef)(!0);(0,q.useEffect)(()=>(c.current=!0,()=>{c.current=!1,s(()=>!0)}),[s]);let l=(0,q.useRef)(e),u=(0,q.useRef)(n);(0,q.useEffect)(()=>{l.current=e,u.current=n});let d=(0,q.useCallback)(({widget:e,props:n,toolCallId:r,release:o})=>{let d=u.current;d?.(`widget`,`agent requested widget "${e}"`,{toolCallId:r,props:n});let f=qt(l.current,e);if(!f)throw Error(`Unknown widget "${e}"`);if(!c.current)throw Error(`The chat is no longer mounted`);let p=Jt(r),m=document.createElement(`div`);m.slot=p,t.append(m);let h;try{h=f.render(n,m)}catch(e){throw m.remove(),e}let g={widget:e,container:m,cleanup:h??void 0,release:o};a.current.set(r,g);let _=s(()=>a.current.size>20);return _>0&&d?.(`widget`,`evicted ${_} widget render(s) past the active cap`,{cap:20}),i(t=>new Map(t).set(p,e)),d?.(`widget`,`widget "${e}" rendered`,{slotName:p}),()=>s(e=>e===g)},[t,s]),[f,p]=(0,q.useState)(e);return f!==e&&(p(e),i(t=>{let n=new Map([...t].filter(([,t])=>qt(e,t)));return n.size===t.size?t:n})),(0,q.useEffect)(()=>{let t=o(t=>!qt(e,t.widget)).length;t>0&&n?.(`widget`,`disposed ${t} render(s) of widgets no longer registered`)},[e,n,o]),{activeSlots:r,renderWidget:d}}const Ef={};function Df({options:e,host:t,controller:n}){let r=e.widgets??Ef,i=(0,q.useMemo)(()=>Ae(e.debug),[e.debug]),{activeSlots:a,renderWidget:o}=Tf(r,t,i),s=wf(e.slots,t,i),c=(0,q.useMemo)(()=>yc(i),[i]),l=(0,q.useMemo)(()=>({agentId:e.agentId,apiUrl:e.apiUrl,fetchAstralBeamToken:e.fetchAstralBeamToken,tools:e.tools,widgets:r,onRenderWidget:o,streamCallbacks:c,debug:e.debug}),[e.agentId,e.apiUrl,e.fetchAstralBeamToken,e.tools,e.debug,r,o,c]),[u]=(0,q.useState)(()=>xf(l,!0));(0,q.useEffect)(()=>{u.updateOptions(l)},[u,l]),(0,q.useEffect)(()=>(u.start(),()=>u.dispose()),[u]);let{messages:d,status:f,error:p,auth:m,capabilities:h,sandbox:g,sandboxStatus:_,agentTools:v}=(0,q.useSyncExternalStore)(u.subscribe,u.getState,u.getState),y=(0,q.useMemo)(()=>new Set(v.map(e=>e.name)),[v]),b=(0,q.useMemo)(()=>{let e={};for(let t of v)t.title!==void 0&&(e[t.name]=t.title);return e},[v]);(0,q.useEffect)(()=>{i?.(`mount`,`tool set declared to the agent`,{tools:[...y],widgets:Object.keys(r)})},[i,y,r]);let x=e.apiUrl??`https://app.astralbeam.ai/api`,S=g.files.length>0||g.commands.length>0;(0,q.useEffect)(()=>{i?.(`status`,`chat status is "${f}"`)},[i,f]);let[C,T]=(0,q.useState)(``),[E,D]=(0,q.useState)([]),O=(0,q.useMemo)(()=>un(h.attachments?e.attachments:!1),[e.attachments,h.attachments]),k=(0,q.useRef)(0),[A,j]=(0,q.useState)(O.enabled);A!==O.enabled&&(j(O.enabled),O.enabled||D([]));let M=f===`submitted`||f===`streaming`,N=M&&!Rt(d),P=m.status===`loading`,F=m.status===`error`?m.error:void 0,I=P||F!==void 0||M||zt(d,y),L=e=>{let t=bn({files:e,existing:E,limits:O,createId:()=>`attachment-${k.current++}`});D(e=>[...e,...t.map(({draft:e})=>e)]);let n=(e,t)=>D(n=>n.map(n=>n.id===e?{...n,...t}:n));for(let{draft:e,file:r}of t){if(e.status===`error`){i?.(`attachment`,`rejected "${e.name}"`,{reason:e.error,size:e.size,type:r.type});continue}i?.(`attachment`,`attached "${e.name}"`,{kind:e.kind,mimeType:e.mimeType,size:e.size}),xn(r).then(t=>n(e.id,{status:`ready`,data:t}),t=>{i?.(`error`,`attachment "${e.name}" could not be read`,t),n(e.id,{status:`error`,error:`The file could not be read`})})}},R=e=>{i?.(`attachment`,`attachment removed`,{id:e}),D(t=>t.filter(t=>t.id!==e))},z=()=>{let e=C.trim(),t=En(E),n=E.some(e=>e.status===`reading`);I||n||e.length===0&&t.length===0||(i?.(`send`,e.length>0?e:`${t.length} attachment(s), no message text`,t.length===0?void 0:{attachments:E.filter(e=>e.status===`ready`).map(e=>({name:e.name,kind:e.kind,size:e.size}))}),u.sendMessage(t.length===0?e:{content:[...t,...e.length>0?[{type:`text`,content:e}]:[]]}),T(``),D([]))},B=(e,t)=>{i?.(`questionnaire`,`answers submitted`,{toolCallId:e,answers:t}),u.addToolResult({toolCallId:e,tool:Mt,output:{answers:t}})},V=()=>{u.reset(),T(``),D([])};(0,q.useImperativeHandle)(n,()=>({reset:V,stop:u.stop}));let H=e.showHeader!==!1;return(0,J.jsxs)(Et,{className:w(`h-full w-full gap-0 rounded-none bg-background text-foreground ring-0`,!H&&`pt-0`),children:[H&&(0,J.jsx)(Dt,{className:`gap-1 border-b`,children:s.has(`header`)?(0,J.jsx)(`slot`,{name:Cf(`header`)}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(Ot,{children:e.title??`AstralBeam`}),(0,J.jsx)(kt,{children:(0,J.jsx)(ie,{variant:`outline`,size:`icon-sm`,"aria-label":`Reset conversation`,disabled:M||d.length===0,onClick:V,children:(0,J.jsx)(tt,{})})})]})}),(0,J.jsx)(At,{className:`min-h-0 flex-1 overflow-hidden p-0`,children:(0,J.jsx)(As,{messages:d,apiUrl:x,emptySlot:s.has(`empty`)?Cf(`empty`):void 0,emptyTitle:e.emptyTitle,emptyDescription:e.emptyDescription,widgets:r,toolTitles:b,activeSlots:a,isBusy:I,awaitingReply:N,onQuestionnaireAnswers:B})}),(0,J.jsxs)(jt,{className:`flex-col gap-2 rounded-none border-t-0 bg-transparent pt-1`,children:[_!==void 0&&(0,J.jsx)(vc,{status:_}),e.sandboxPanel===!0&&S&&(0,J.jsx)(gc,{activity:g}),(0,J.jsx)(Un,{title:e.title??`AstralBeam`,actionsSlot:s.has(`composerActions`)?Cf(`composerActions`):void 0,draft:C,onDraftChange:T,onSend:z,onStop:()=>{i?.(`status`,`generation stopped by user`),u.stop()},onRetry:d.length>0?()=>void u.reload():void 0,showError:f===`error`,error:p,streamBusy:M,isBusy:I,authPending:P,authError:F,onAuthRetry:u.retryAuthentication,attachments:E,attachmentLimits:O,onAddFiles:L,onRemoveAttachment:R})]})]})}function Of(e,t){let n=e.host.parentElement??document.body,r=$t(),i=document.createElement(`style`);e.append(i);let a=()=>{i.textContent=en(n,r),t()?.(`theme`,`host style bridged onto widget slots`,{rule:i.textContent})};a();let o=0,s=()=>{cancelAnimationFrame(o),o=requestAnimationFrame(a)},c=[];for(let e=n;e;e=e.parentElement){let t=new MutationObserver(s);t.observe(e,{attributeFilter:[`class`,`style`]}),c.push(t)}return()=>{cancelAnimationFrame(o);for(let e of c)e.disconnect();i.remove()}}function kf(e,t,n){let r=document.createElement(`style`);r.textContent=ye+(n.customCss??``),e.append(r);let i=n,a=Of(e,()=>Ae(i.debug)),o=(0,Tt.createRoot)(t),s=(0,q.createRef)(),c=t=>{i.customCss!==t.customCss&&(r.textContent=ye+(t.customCss??``)),i=t,o.render((0,J.jsx)(Df,{options:t,host:e.host,controller:s}))};return c(n),{update:c,reset:()=>s.current?.reset(),stop:()=>s.current?.stop(),dispose:()=>{o.unmount(),a(),r.remove()}}}export{kf as renderChat};
20
+ `),inputSchema:{type:`object`,properties:{widget:{type:`string`,enum:Object.keys(e),description:`Name of the widget to render.`},props:{type:`object`,description:`Props for the widget, matching its props schema.`}},required:[`widget`]}}).client((e,n)=>t(e,n?.toolCallId??``))}function vf(){return su({name:Mt,description:`Ask the user a short structured questionnaire rendered inline in the chat. Use it when the next step genuinely depends on their choices instead of asking in prose. The call stays pending until the user submits; their answers arrive as the tool output. Skipped optional questions come back with an empty answers array. An output with skipped: true means the user dismissed the questionnaire by continuing the conversation instead — do not re-ask; address their next message.`,inputSchema:{type:`object`,properties:{items:{type:`array`,minItems:1,description:`Questions shown one at a time, in order.`,items:{type:`object`,properties:{name:{type:`string`,description:`Unique key identifying the question.`},title:{type:`string`,description:`The question itself.`},description:{type:`string`,description:`Optional helper text.`},required:{type:`boolean`,description:`Whether an answer is mandatory.`},multiple:{type:`boolean`,description:`Whether several choices may be selected.`},choices:{type:`array`,minItems:1,items:{type:`object`,properties:{value:{type:`string`},label:{type:`string`},description:{type:`string`}},required:[`value`,`label`]}},input:{type:`object`,description:`Optional free-form alternative to the fixed choices.`,properties:{label:{type:`string`},placeholder:{type:`string`}},required:[`label`,`placeholder`]}},required:[`name`,`title`,`choices`]}}},required:[`items`]}}).client()}function yf(e,t){return Object.entries(e).map(([e,n])=>su({name:e,description:n.description,inputSchema:mf(n.parameters),...n.metadata?{metadata:n.metadata}:{}}).client(async r=>{t?.(`tool`,`executing host tool "${e}"`,{input:r});let i=await hf(n.parameters,r??{});if(i==null)throw t?.(`error`,`input for host tool "${e}" failed schema validation`,{input:r}),Error(`Input for tool "${e}" failed schema validation`);try{let r=await n.execute(i);try{Bc(r)}catch{throw Error(`Tool "${e}" ran, but its result is not JSON-compatible. Its changes may already be applied. Read current state before retrying. Return plain JSON values and omit undefined fields.`)}return t?.(`tool`,`host tool "${e}" returned`,{output:r}),r}catch(n){throw t?.(`error`,`host tool "${e}" threw`,{error:n}),n}}))}function bf(e,t){return e.length===t.length&&e.every((e,n)=>e.name===t[n]?.name&&e.title===t[n]?.title)}function xf(e,t=!1){let n={...e},r=Ae(n.debug),a=new Set,o={messages:[],status:`ready`,error:void 0,auth:{status:`loading`},capabilities:{attachments:!0},agentTools:[],sandboxStatus:void 0,sandbox:{files:[],commands:[]}},s=e=>{o={...o,...e};for(let e of a)e()},c=E({apiUrl:n.apiUrl,scope:`tenant`,fetchAstralBeamToken:n.fetchAstralBeamToken??{url:`/api/astralbeam/token`}}),l,u,d,f=!1,p=0,m,h=async()=>{let e=++p;try{let t=await A(c);if(e!==p)return;let i=await Se(n.agentId?{agentId:n.agentId}:{},{apiUrl:c.apiUrl,astralBeamToken:t,signal:c.session.abortController.signal,fetchClient:(e,t)=>ge({...c,input:e,init:t})});if(e!==p)return;let a=i.capabilities?.attachments!==!1;s({capabilities:{attachments:a}}),r?.(`mount`,`agent capabilities resolved`,{attachments:a})}catch(e){r?.(`error`,`agent capabilities could not be resolved; keeping the defaults`,e)}},g=new Map,v=()=>{for(let e of g.values())e();g.clear()},y=async(e,t)=>{let r=n.widgets??{};if(!Object.hasOwn(r,e.widget))throw Error(`Unknown widget "${e.widget}"`);let i=r[e.widget],a=await hf(i?.parameters,e.props??{});if(a==null)throw Error(`Props for widget "${e.widget}" failed validation`);g.get(t)?.(),g.delete(t);let o,s=n.onRenderWidget?.({widget:e.widget,props:a,toolCallId:t,release:()=>{g.get(t)===o&&g.delete(t)}});return s&&(o=s,g.set(t,s)),{widget:e.widget,rendered:n.onRenderWidget!==void 0}},b=()=>gf(n.widgets??{},n.tools??{},y,r),x=()=>{let e=b(),t=e.map(e=>{let t=e.metadata?.title;return{name:e.name,title:typeof t==`string`&&t.length>0?t:void 0}});return bf(o.agentTools,t)||s({agentTools:t}),e},S=()=>({...n.agentId?{agentId:n.agentId}:{},...n.debug?{debug:!0}:{}}),C=dd(()=>i(O(),c.apiUrl),async()=>{let e=d,t=await A(c);if(e!==void 0&&e!==d)throw new DOMException(`Identity changed`,`AbortError`);return{fetchClient:(e,n)=>Te(O(),{...n,apiUrl:c.apiUrl,astralBeamToken:t,fetchClient:(e,t)=>ge({...c,input:e,init:t})})}}),w=C.connect;C.connect=async function*(...e){try{yield*w(...e)}catch(e){throw e instanceof Error&&_(e.cause)?e.cause:e}};let T=new pf({connection:C,tools:x(),forwardedProps:S(),onMessagesChange:e=>{s({messages:e,sandbox:_i(e),error:T.getError()})},onStatusChange:e=>s({status:e,error:T.getError()}),onCustomEvent:(e,t)=>{let n=t?.state;if(e===`astralbeam.sandbox.status`&&(n===`starting`||n===`ready`||n===`error`)){r?.(`sandbox`,`sandbox ${n}`),s({sandboxStatus:n});return}r?.(`stream`,`custom event "${e}"`,t)},onChunk:e=>n.streamCallbacks?.onChunk?.(e),onResponse:e=>n.streamCallbacks?.onResponse?.(e),onFinish:e=>n.streamCallbacks?.onFinish?.(e),onError:e=>n.streamCallbacks?.onError?.(e)}),D=()=>{for(let e of o.messages)for(let t of e.parts)t.type!==`tool-call`||Lt(t)||(t.name===`ask_questionnaire`?(r?.(`questionnaire`,`skipping pending questionnaire before send`,{id:t.id}),T.addToolResult({toolCallId:t.id,tool:t.name,output:{answers:[],skipped:!0}})):(r?.(`tool`,`settling unimplemented tool call "${t.name}" as error`,{id:t.id}),T.addToolResult({toolCallId:t.id,tool:t.name,output:null,state:`output-error`,errorText:`The application hosting this chat has no implementation for "${t.name}"`})))},k=()=>{let e=H(c);if(e.status===`ready`){let t=me(e.currentUser);d!==void 0&&d!==t&&(T.stop(),T.clear(),v(),s({messages:[],sandbox:{files:[],commands:[]},sandboxStatus:void 0})),d=t,m!==t&&(m=t,h())}s({auth:e})},j=()=>{f||(f=!0,u=xe(c,k),k(),l=oe(c))};return t||j(),{start:j,getState:()=>o,subscribe:e=>(a.add(e),()=>a.delete(e)),updateOptions:e=>{let t=n.agentId,i=n.apiUrl;n={...n,...e},r=Ae(n.debug),M(c,{apiUrl:n.apiUrl,fetchAstralBeamToken:n.fetchAstralBeamToken??{url:`/api/astralbeam/token`}}),c.debug=r,T.updateOptions({tools:x(),forwardedProps:S()}),f&&(n.agentId!==t||n.apiUrl!==i)&&h()},sendMessage:e=>(D(),T.sendMessage(e)),addToolResult:e=>T.addToolResult(e),stop:()=>T.stop(),retryAuthentication:()=>{A({...c,force:!0}).catch(()=>void 0)},reload:()=>T.reload(),reset:()=>{r?.(`status`,`conversation reset`),T.clear(),v(),s({messages:[],sandbox:{files:[],commands:[]},sandboxStatus:void 0,error:void 0})},dispose:()=>{v(),T.stop(),p++,m=void 0,l?.(),u?.(),le(c),f=!1,queueMicrotask(()=>{f||T.dispose()}),a.clear()}}}const Sf=[`header`,`empty`,`composerActions`];function Cf(e){return`${Vt}${e===`composerActions`?`composer-actions`:e}`}function wf(e,t,n){let[r,i]=(0,q.useState)(new Set),a=(0,q.useRef)(new Map);return(0,q.useEffect)(()=>{for(let r of Sf){let i=e?.[r],o=a.current.get(r);if(o?.renderer===i||(o&&(o.cleanup?.(),o.container.remove(),a.current.delete(r),n?.(`mount`,`host slot "${r}" disposed`)),!i))continue;let s=document.createElement(`div`);s.slot=Cf(r),t.append(s);let c=i(s);a.current.set(r,{renderer:i,container:s,cleanup:c??void 0}),n?.(`mount`,`host slot "${r}" rendered`)}i(e=>{let t=new Set(a.current.keys());return t.size===e.size&&[...t].every(t=>e.has(t))?e:t})},[e,t,n]),(0,q.useEffect)(()=>()=>{for(let e of a.current.values())e.cleanup?.(),e.container.remove();a.current.clear()},[]),r}function Tf(e,t,n){let[r,i]=(0,q.useState)(new Map),a=(0,q.useRef)(new Map),o=(0,q.useCallback)(e=>{let t=[];for(let[n,r]of a.current)e(r)&&(r.cleanup?.(),r.container.remove(),r.release(),a.current.delete(n),t.push(Jt(n)));return t},[]),s=(0,q.useCallback)(e=>{let t=o(e);return t.length>0&&i(e=>{let n=new Map(e);for(let e of t)n.delete(e);return n}),t.length},[o]),c=(0,q.useRef)(!0);(0,q.useEffect)(()=>(c.current=!0,()=>{c.current=!1,s(()=>!0)}),[s]);let l=(0,q.useRef)(e),u=(0,q.useRef)(n);(0,q.useEffect)(()=>{l.current=e,u.current=n});let d=(0,q.useCallback)(({widget:e,props:n,toolCallId:r,release:o})=>{let d=u.current;d?.(`widget`,`agent requested widget "${e}"`,{toolCallId:r,props:n});let f=qt(l.current,e);if(!f)throw Error(`Unknown widget "${e}"`);if(!c.current)throw Error(`The chat is no longer mounted`);let p=Jt(r),m=document.createElement(`div`);m.slot=p,t.append(m);let h;try{h=f.render(n,m)}catch(e){throw m.remove(),e}let g={widget:e,container:m,cleanup:h??void 0,release:o};a.current.set(r,g);let _=s(()=>a.current.size>20);return _>0&&d?.(`widget`,`evicted ${_} widget render(s) past the active cap`,{cap:20}),i(t=>new Map(t).set(p,e)),d?.(`widget`,`widget "${e}" rendered`,{slotName:p}),()=>s(e=>e===g)},[t,s]),[f,p]=(0,q.useState)(e);return f!==e&&(p(e),i(t=>{let n=new Map([...t].filter(([,t])=>qt(e,t)));return n.size===t.size?t:n})),(0,q.useEffect)(()=>{let t=o(t=>!qt(e,t.widget)).length;t>0&&n?.(`widget`,`disposed ${t} render(s) of widgets no longer registered`)},[e,n,o]),{activeSlots:r,renderWidget:d}}const Ef={};function Df({options:e,host:t,controller:n}){let r=e.widgets??Ef,i=(0,q.useMemo)(()=>Ae(e.debug),[e.debug]),{activeSlots:a,renderWidget:o}=Tf(r,t,i),s=wf(e.slots,t,i),c=(0,q.useMemo)(()=>yc(i),[i]),l=(0,q.useMemo)(()=>({agentId:e.agentId,apiUrl:e.apiUrl,fetchAstralBeamToken:e.fetchAstralBeamToken,tools:e.tools,widgets:r,onRenderWidget:o,streamCallbacks:c,debug:e.debug}),[e.agentId,e.apiUrl,e.fetchAstralBeamToken,e.tools,e.debug,r,o,c]),[u]=(0,q.useState)(()=>xf(l,!0));(0,q.useEffect)(()=>{u.updateOptions(l)},[u,l]),(0,q.useEffect)(()=>(u.start(),()=>u.dispose()),[u]);let{messages:d,status:f,error:p,auth:m,capabilities:h,sandbox:g,sandboxStatus:_,agentTools:v}=(0,q.useSyncExternalStore)(u.subscribe,u.getState,u.getState),y=(0,q.useMemo)(()=>new Set(v.map(e=>e.name)),[v]),b=(0,q.useMemo)(()=>{let e={};for(let t of v)t.title!==void 0&&(e[t.name]=t.title);return e},[v]);(0,q.useEffect)(()=>{i?.(`mount`,`tool set declared to the agent`,{tools:[...y],widgets:Object.keys(r)})},[i,y,r]);let x=e.apiUrl??`https://app.astralbeam.ai/api`,S=g.files.length>0||g.commands.length>0;(0,q.useEffect)(()=>{i?.(`status`,`chat status is "${f}"`)},[i,f]);let[C,T]=(0,q.useState)(``),[E,D]=(0,q.useState)([]),O=(0,q.useMemo)(()=>un(h.attachments?e.attachments:!1),[e.attachments,h.attachments]),k=(0,q.useRef)(0),[A,j]=(0,q.useState)(O.enabled);A!==O.enabled&&(j(O.enabled),O.enabled||D([]));let M=f===`submitted`||f===`streaming`,N=M&&!Rt(d),P=m.status===`loading`,F=m.status===`error`?m.error:void 0,I=P||F!==void 0||M||zt(d,y),L=e=>{let t=bn({files:e,existing:E,limits:O,createId:()=>`attachment-${k.current++}`});D(e=>[...e,...t.map(({draft:e})=>e)]);let n=(e,t)=>D(n=>n.map(n=>n.id===e?{...n,...t}:n));for(let{draft:e,file:r}of t){if(e.status===`error`){i?.(`attachment`,`rejected "${e.name}"`,{reason:e.error,size:e.size,type:r.type});continue}i?.(`attachment`,`attached "${e.name}"`,{kind:e.kind,mimeType:e.mimeType,size:e.size}),xn(r).then(t=>n(e.id,{status:`ready`,data:t}),t=>{i?.(`error`,`attachment "${e.name}" could not be read`,t),n(e.id,{status:`error`,error:`The file could not be read`})})}},R=e=>{i?.(`attachment`,`attachment removed`,{id:e}),D(t=>t.filter(t=>t.id!==e))},z=()=>{let e=C.trim(),t=En(E),n=E.some(e=>e.status===`reading`);I||n||e.length===0&&t.length===0||(i?.(`send`,e.length>0?e:`${t.length} attachment(s), no message text`,t.length===0?void 0:{attachments:E.filter(e=>e.status===`ready`).map(e=>({name:e.name,kind:e.kind,size:e.size}))}),u.sendMessage(t.length===0?e:{content:[...t,...e.length>0?[{type:`text`,content:e}]:[]]}),T(``),D([]))},B=(e,t)=>{i?.(`questionnaire`,`answers submitted`,{toolCallId:e,answers:t}),u.addToolResult({toolCallId:e,tool:Mt,output:{answers:t}})},V=()=>{u.reset(),T(``),D([])};(0,q.useImperativeHandle)(n,()=>({reset:V,stop:u.stop}));let H=e.showHeader!==!1;return(0,J.jsxs)(Et,{className:w(`h-full w-full gap-0 rounded-none bg-background text-foreground ring-0`,!H&&`pt-0`),children:[H&&(0,J.jsx)(Dt,{className:`gap-1 border-b`,children:s.has(`header`)?(0,J.jsx)(`slot`,{name:Cf(`header`)}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(Ot,{children:e.title??`AstralBeam`}),(0,J.jsx)(kt,{children:(0,J.jsx)(ie,{variant:`outline`,size:`icon-sm`,"aria-label":`Reset conversation`,disabled:M||d.length===0,onClick:V,children:(0,J.jsx)(tt,{})})})]})}),(0,J.jsx)(At,{className:`min-h-0 flex-1 overflow-hidden p-0`,children:(0,J.jsx)(As,{messages:d,apiUrl:x,emptySlot:s.has(`empty`)?Cf(`empty`):void 0,emptyTitle:e.emptyTitle,emptyDescription:e.emptyDescription,widgets:r,toolTitles:b,activeSlots:a,isBusy:I,awaitingReply:N,onQuestionnaireAnswers:B})}),(0,J.jsxs)(jt,{className:`flex-col gap-2 rounded-none border-t-0 bg-transparent pt-1`,children:[_!==void 0&&(0,J.jsx)(vc,{status:_}),e.sandboxPanel===!0&&S&&(0,J.jsx)(gc,{activity:g}),(0,J.jsx)(Un,{title:e.title??`AstralBeam`,actionsSlot:s.has(`composerActions`)?Cf(`composerActions`):void 0,draft:C,onDraftChange:T,onSend:z,onStop:()=>{i?.(`status`,`generation stopped by user`),u.stop()},onRetry:d.length>0?()=>void u.reload():void 0,showError:f===`error`,error:p,streamBusy:M,isBusy:I,authPending:P,authError:F,onAuthRetry:u.retryAuthentication,attachments:E,attachmentLimits:O,onAddFiles:L,onRemoveAttachment:R})]})]})}function Of(e,t){let n=e.host.parentElement??document.body,r=$t(),i=document.createElement(`style`);e.append(i);let a=()=>{i.textContent=en(n,r),t()?.(`theme`,`host style bridged onto widget slots`,{rule:i.textContent})};a();let o=0,s=()=>{cancelAnimationFrame(o),o=requestAnimationFrame(a)},c=[];for(let e=n;e;e=e.parentElement){let t=new MutationObserver(s);t.observe(e,{attributeFilter:[`class`,`style`]}),c.push(t)}return()=>{cancelAnimationFrame(o);for(let e of c)e.disconnect();i.remove()}}function kf(e,t,n){let r=document.createElement(`style`);r.textContent=ye+(n.customCss??``),e.append(r);let i=n,a=Of(e,()=>Ae(i.debug)),o=(0,Tt.createRoot)(t),s=(0,q.createRef)(),c=t=>{i.customCss!==t.customCss&&(r.textContent=ye+(t.customCss??``)),i=t,o.render((0,J.jsx)(Df,{options:t,host:e.host,controller:s}))};return c(n),{update:c,reset:()=>s.current?.reset(),stop:()=>s.current?.stop(),dispose:()=>{o.unmount(),a(),r.remove()}}}export{kf as renderChat};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astralbeam/sdk",
3
- "version": "0.13.4",
3
+ "version": "0.13.6",
4
4
  "description": "Frontend SDK for AstralBeam: drop-in agent UI, chat streaming, and server helpers",
5
5
  "homepage": "https://astralbeam.ai",
6
6
  "bugs": "https://github.com/AstralBeamAI/astralbeam/issues",