@ably/ai-transport 0.1.0 → 0.2.0

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.
Files changed (163) hide show
  1. package/README.md +91 -100
  2. package/dist/ably-ai-transport.js +1553 -1238
  3. package/dist/ably-ai-transport.js.map +1 -1
  4. package/dist/ably-ai-transport.umd.cjs +1 -1
  5. package/dist/ably-ai-transport.umd.cjs.map +1 -1
  6. package/dist/constants.d.ts +116 -42
  7. package/dist/core/agent.d.ts +29 -0
  8. package/dist/core/codec/decoder.d.ts +20 -23
  9. package/dist/core/codec/encoder.d.ts +11 -8
  10. package/dist/core/codec/index.d.ts +1 -2
  11. package/dist/core/codec/lifecycle-tracker.d.ts +10 -9
  12. package/dist/core/codec/types.d.ts +407 -115
  13. package/dist/core/transport/agent-session.d.ts +10 -0
  14. package/dist/core/transport/branch-chain.d.ts +43 -0
  15. package/dist/core/transport/client-session.d.ts +13 -0
  16. package/dist/core/transport/decode-fold.d.ts +47 -0
  17. package/dist/core/transport/headers.d.ts +96 -18
  18. package/dist/core/transport/index.d.ts +5 -6
  19. package/dist/core/transport/internal/bounded-map.d.ts +20 -0
  20. package/dist/core/transport/invocation.d.ts +74 -0
  21. package/dist/core/transport/load-conversation.d.ts +128 -0
  22. package/dist/core/transport/load-history.d.ts +39 -0
  23. package/dist/core/transport/pipe-stream.d.ts +9 -9
  24. package/dist/core/transport/run-manager.d.ts +78 -0
  25. package/dist/core/transport/tree.d.ts +373 -109
  26. package/dist/core/transport/types/agent.d.ts +353 -0
  27. package/dist/core/transport/types/client.d.ts +168 -0
  28. package/dist/core/transport/types/shared.d.ts +24 -0
  29. package/dist/core/transport/types/tree.d.ts +315 -0
  30. package/dist/core/transport/types/view.d.ts +222 -0
  31. package/dist/core/transport/types.d.ts +13 -553
  32. package/dist/core/transport/view.d.ts +272 -84
  33. package/dist/errors.d.ts +21 -10
  34. package/dist/index.d.ts +6 -8
  35. package/dist/logger.d.ts +12 -0
  36. package/dist/react/ably-ai-transport-react.js +976 -990
  37. package/dist/react/ably-ai-transport-react.js.map +1 -1
  38. package/dist/react/ably-ai-transport-react.umd.cjs +1 -1
  39. package/dist/react/ably-ai-transport-react.umd.cjs.map +1 -1
  40. package/dist/react/contexts/client-session-context.d.ts +36 -0
  41. package/dist/react/contexts/client-session-provider.d.ts +53 -0
  42. package/dist/react/create-session-hooks.d.ts +116 -0
  43. package/dist/react/index.d.ts +12 -12
  44. package/dist/react/internal/use-resolved-session.d.ts +36 -0
  45. package/dist/react/use-ably-messages.d.ts +17 -14
  46. package/dist/react/use-client-session.d.ts +81 -0
  47. package/dist/react/use-create-view.d.ts +14 -13
  48. package/dist/react/use-tree.d.ts +30 -15
  49. package/dist/react/use-view.d.ts +82 -51
  50. package/dist/utils.d.ts +32 -23
  51. package/dist/vercel/ably-ai-transport-vercel.js +2573 -2086
  52. package/dist/vercel/ably-ai-transport-vercel.js.map +1 -1
  53. package/dist/vercel/ably-ai-transport-vercel.umd.cjs +1 -1
  54. package/dist/vercel/ably-ai-transport-vercel.umd.cjs.map +1 -1
  55. package/dist/vercel/codec/decoder.d.ts +5 -18
  56. package/dist/vercel/codec/encoder.d.ts +6 -36
  57. package/dist/vercel/codec/events.d.ts +51 -0
  58. package/dist/vercel/codec/index.d.ts +24 -12
  59. package/dist/vercel/codec/reducer.d.ts +144 -0
  60. package/dist/vercel/codec/tool-transitions.d.ts +2 -2
  61. package/dist/vercel/index.d.ts +4 -5
  62. package/dist/vercel/react/ably-ai-transport-vercel-react.js +3907 -3266
  63. package/dist/vercel/react/ably-ai-transport-vercel-react.js.map +1 -1
  64. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs +33 -8
  65. package/dist/vercel/react/ably-ai-transport-vercel-react.umd.cjs.map +1 -1
  66. package/dist/vercel/react/contexts/chat-transport-context.d.ts +7 -6
  67. package/dist/vercel/react/contexts/chat-transport-provider.d.ts +53 -41
  68. package/dist/vercel/react/index.d.ts +1 -2
  69. package/dist/vercel/react/use-chat-transport.d.ts +30 -26
  70. package/dist/vercel/react/use-message-sync.d.ts +17 -30
  71. package/dist/vercel/run-end-reason.d.ts +29 -0
  72. package/dist/vercel/transport/chat-transport.d.ts +43 -24
  73. package/dist/vercel/transport/index.d.ts +25 -21
  74. package/dist/vercel/transport/run-output-stream.d.ts +56 -0
  75. package/dist/version.d.ts +2 -0
  76. package/package.json +30 -23
  77. package/src/constants.ts +124 -51
  78. package/src/core/agent.ts +68 -0
  79. package/src/core/codec/decoder.ts +71 -98
  80. package/src/core/codec/encoder.ts +113 -65
  81. package/src/core/codec/index.ts +13 -6
  82. package/src/core/codec/lifecycle-tracker.ts +10 -9
  83. package/src/core/codec/types.ts +436 -120
  84. package/src/core/transport/agent-session.ts +1344 -0
  85. package/src/core/transport/branch-chain.ts +58 -0
  86. package/src/core/transport/client-session.ts +775 -0
  87. package/src/core/transport/decode-fold.ts +91 -0
  88. package/src/core/transport/headers.ts +181 -22
  89. package/src/core/transport/index.ts +25 -26
  90. package/src/core/transport/internal/bounded-map.ts +27 -0
  91. package/src/core/transport/invocation.ts +98 -0
  92. package/src/core/transport/load-conversation.ts +355 -0
  93. package/src/core/transport/load-history.ts +269 -0
  94. package/src/core/transport/pipe-stream.ts +54 -39
  95. package/src/core/transport/run-manager.ts +249 -0
  96. package/src/core/transport/tree.ts +926 -308
  97. package/src/core/transport/types/agent.ts +407 -0
  98. package/src/core/transport/types/client.ts +211 -0
  99. package/src/core/transport/types/shared.ts +27 -0
  100. package/src/core/transport/types/tree.ts +344 -0
  101. package/src/core/transport/types/view.ts +259 -0
  102. package/src/core/transport/types.ts +13 -706
  103. package/src/core/transport/view.ts +864 -433
  104. package/src/errors.ts +22 -9
  105. package/src/event-emitter.ts +3 -2
  106. package/src/index.ts +52 -41
  107. package/src/logger.ts +14 -1
  108. package/src/react/contexts/client-session-context.ts +41 -0
  109. package/src/react/contexts/client-session-provider.tsx +186 -0
  110. package/src/react/create-session-hooks.ts +141 -0
  111. package/src/react/index.ts +23 -13
  112. package/src/react/internal/use-resolved-session.ts +63 -0
  113. package/src/react/use-ably-messages.ts +32 -22
  114. package/src/react/use-client-session.ts +201 -0
  115. package/src/react/use-create-view.ts +33 -29
  116. package/src/react/use-tree.ts +61 -30
  117. package/src/react/use-view.ts +139 -97
  118. package/src/utils.ts +63 -45
  119. package/src/vercel/codec/decoder.ts +336 -258
  120. package/src/vercel/codec/encoder.ts +343 -205
  121. package/src/vercel/codec/events.ts +87 -0
  122. package/src/vercel/codec/index.ts +60 -13
  123. package/src/vercel/codec/reducer.ts +977 -0
  124. package/src/vercel/codec/tool-transitions.ts +2 -2
  125. package/src/vercel/index.ts +6 -19
  126. package/src/vercel/react/contexts/chat-transport-context.ts +7 -6
  127. package/src/vercel/react/contexts/chat-transport-provider.tsx +87 -59
  128. package/src/vercel/react/index.ts +3 -5
  129. package/src/vercel/react/use-chat-transport.ts +47 -49
  130. package/src/vercel/react/use-message-sync.ts +80 -39
  131. package/src/vercel/run-end-reason.ts +78 -0
  132. package/src/vercel/transport/chat-transport.ts +392 -98
  133. package/src/vercel/transport/index.ts +39 -38
  134. package/src/vercel/transport/run-output-stream.ts +170 -0
  135. package/src/version.ts +2 -0
  136. package/dist/core/transport/client-transport.d.ts +0 -10
  137. package/dist/core/transport/decode-history.d.ts +0 -43
  138. package/dist/core/transport/server-transport.d.ts +0 -7
  139. package/dist/core/transport/stream-router.d.ts +0 -29
  140. package/dist/core/transport/turn-manager.d.ts +0 -37
  141. package/dist/react/contexts/transport-context.d.ts +0 -31
  142. package/dist/react/contexts/transport-provider.d.ts +0 -49
  143. package/dist/react/create-transport-hooks.d.ts +0 -124
  144. package/dist/react/use-active-turns.d.ts +0 -12
  145. package/dist/react/use-client-transport.d.ts +0 -80
  146. package/dist/vercel/codec/accumulator.d.ts +0 -21
  147. package/dist/vercel/react/use-staged-add-tool-approval-response.d.ts +0 -30
  148. package/dist/vercel/tool-approvals.d.ts +0 -124
  149. package/dist/vercel/tool-events.d.ts +0 -26
  150. package/src/core/transport/client-transport.ts +0 -977
  151. package/src/core/transport/decode-history.ts +0 -485
  152. package/src/core/transport/server-transport.ts +0 -612
  153. package/src/core/transport/stream-router.ts +0 -136
  154. package/src/core/transport/turn-manager.ts +0 -165
  155. package/src/react/contexts/transport-context.ts +0 -37
  156. package/src/react/contexts/transport-provider.tsx +0 -164
  157. package/src/react/create-transport-hooks.ts +0 -144
  158. package/src/react/use-active-turns.ts +0 -72
  159. package/src/react/use-client-transport.ts +0 -197
  160. package/src/vercel/codec/accumulator.ts +0 -588
  161. package/src/vercel/react/use-staged-add-tool-approval-response.ts +0 -87
  162. package/src/vercel/tool-approvals.ts +0 -380
  163. package/src/vercel/tool-events.ts +0 -53
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`ably`)):typeof define==`function`&&define.amd?define([`exports`,`ably`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.AblyAiTransport={},e.Ably))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),c(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t,1);var l=`x-ably-stream`,u=`x-ably-status`,d=`x-ably-stream-id`,f=`x-ably-discrete`,p=`x-ably-turn-id`,m=`x-ably-msg-id`,h=`x-ably-turn-client-id`,g=`x-ably-role`,_=`x-ably-amend`,v=`x-ably-cancel-turn-id`,y=`x-ably-cancel-own`,b=`x-ably-cancel-all`,x=`x-ably-cancel-client-id`,S=`x-ably-parent`,C=`x-ably-fork-of`,w=`x-ably-turn-reason`,T=`x-ably-cancel`,E=`x-ably-turn-start`,D=`x-ably-turn-end`,ee=`x-ably-abort`,te=`x-ably-error`,O=`x-domain-`,k=function(e){return e[e.BadRequest=4e4]=`BadRequest`,e[e.InvalidArgument=40003]=`InvalidArgument`,e[e.EncoderRecoveryFailed=104e3]=`EncoderRecoveryFailed`,e[e.TransportSubscriptionError=104001]=`TransportSubscriptionError`,e[e.CancelListenerError=104002]=`CancelListenerError`,e[e.TurnLifecycleError=104003]=`TurnLifecycleError`,e[e.TransportClosed=104004]=`TransportClosed`,e[e.TransportSendFailed=104005]=`TransportSendFailed`,e[e.ChannelContinuityLost=104006]=`ChannelContinuityLost`,e[e.ChannelNotReady=104007]=`ChannelNotReady`,e[e.StreamError=104008]=`StreamError`,e}({}),A=(e,t)=>e.code===t,j=e=>{let t=e.extras;if(!t||typeof t!=`object`)return{};let n=t.headers;return!n||typeof n!=`object`?{}:n},ne=e=>{if(e!==void 0)try{return JSON.parse(e)}catch{return}},M=(e,t)=>({...e,...t}),N=e=>{if(e!==void 0)return e===`true`},P=(e,t)=>e[O+t],F=e=>{let t={};for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&e[n]!==void 0&&(t[n]=e[n]);return t},re=e=>({str:t=>P(e,t),strOr:(t,n)=>P(e,t)??n,bool:t=>N(P(e,t)),json:t=>ne(P(e,t))}),ie=()=>{let e={},t={str:(n,r)=>(r!==void 0&&(e[O+n]=r),t),bool:(n,r)=>(r!==void 0&&(e[O+n]=String(r)),t),json:(n,r)=>(r!=null&&(e[O+n]=JSON.stringify(r)),t),build:()=>e};return t},I=e=>{let t={[g]:e.role,[p]:e.turnId,[m]:e.msgId};return e.turnClientId!==void 0&&(t[h]=e.turnClientId),e.parent&&(t[S]=e.parent),e.forkOf&&(t[C]=e.forkOf),e.amend&&(t[_]=e.amend),t},ae=async(e,t,n,r,i,a)=>{a?.trace(`pipeStream();`);let o=e.getReader(),s,c=n?new Promise(e=>{if(n.aborted){e();return}s=()=>{e()},n.addEventListener(`abort`,s,{once:!0})}):new Promise(()=>{}),l=`complete`,u;try{for(;;){let e=await Promise.race([o.read(),c.then(()=>`aborted`)]);if(e===`aborted`){l=`cancelled`,a?.debug(`pipeStream(); stream cancelled by abort signal`),r&&await r(async e=>t.appendEvent(e)),await t.abort(`cancelled`);break}let{done:n,value:s}=e;if(n){await t.close(),a?.debug(`pipeStream(); stream completed`);break}await t.appendEvent(s,i?.(s))}}catch(e){l=`error`,u=e instanceof Error?e:Error(String(e)),a?.error(`pipeStream(); stream error`,{error:u.message});try{await t.close()}catch{}}finally{s&&n?.removeEventListener(`abort`,s),o.releaseLock()}return{reason:l,error:u}},oe=class{constructor(e,t){this._activeTurns=new Map,this._channel=e,this._logger=t?.withContext({component:`TurnManager`})}async startTurn(e,t,n,r){this._logger?.trace(`DefaultTurnManager.startTurn();`,{turnId:e,clientId:t});let i=n??new AbortController,a=t??``;this._activeTurns.set(e,{controller:i,clientId:a});let o={[p]:e,[h]:a};return r?.parent!==void 0&&(o[S]=r.parent),r?.forkOf!==void 0&&(o[C]=r.forkOf),await this._channel.publish({name:E,extras:{headers:o}}),this._logger?.debug(`DefaultTurnManager.startTurn(); turn started`,{turnId:e}),i.signal}async endTurn(e,t){this._logger?.trace(`DefaultTurnManager.endTurn();`,{turnId:e,reason:t});let n=this._activeTurns.get(e)?.clientId??``;await this._channel.publish({name:D,extras:{headers:{[p]:e,[h]:n,[w]:t}}}),this._activeTurns.delete(e),this._logger?.debug(`DefaultTurnManager.endTurn(); turn ended`,{turnId:e,reason:t})}getSignal(e){return this._activeTurns.get(e)?.controller.signal}getClientId(e){return this._activeTurns.get(e)?.clientId}abort(e){this._logger?.debug(`DefaultTurnManager.abort();`,{turnId:e}),this._activeTurns.get(e)?.controller.abort()}getActiveTurnIds(){return[...this._activeTurns.keys()]}close(){this._logger?.trace(`DefaultTurnManager.close();`,{activeTurns:this._activeTurns.size});for(let e of this._activeTurns.values())e.controller.abort();this._activeTurns.clear()}},se=(e,t)=>new oe(e,t),L=function(e){return e.READY=`ready`,e.CLOSED=`closed`,e}(L||{}),R=function(e){return e.INITIALIZED=`initialized`,e.STARTED=`started`,e.ENDED=`ended`,e}(R||{}),ce=class{constructor(e){this._registeredTurns=new Map,this._state=L.READY,this._channel=e.channel,this._codec=e.codec,this._logger=e.logger?.withContext({component:`ServerTransport`}),this._onError=e.onError,this._turnManager=se(this._channel,this._logger),this._channelListener=e=>{this._handleChannelMessage(e)},this._attachPromise=this._channel.subscribe(T,this._channelListener).then(()=>{},e=>{let n=new t.ErrorInfo(`unable to subscribe to cancel messages; ${e instanceof Error?e.message:String(e)}`,k.TransportSubscriptionError,500,e instanceof t.ErrorInfo?e:void 0);this._logger?.error(`DefaultServerTransport(); subscribe failed`),this._onError?.(n)}),this._hasAttachedOnce=this._channel.state===`attached`,this._onChannelStateChange=e=>{this._handleChannelStateChange(e)},this._channel.on(this._onChannelStateChange),this._logger?.debug(`DefaultServerTransport(); transport created`)}newTurn(e){return this._logger?.trace(`DefaultServerTransport.newTurn();`,{turnId:e.turnId}),this._createTurn(e)}close(){if(this._state!==L.CLOSED){this._state=L.CLOSED,this._logger?.trace(`DefaultServerTransport.close();`),this._channel.unsubscribe(T,this._channelListener),this._channel.off(this._onChannelStateChange);for(let e of this._registeredTurns.values())e.controller.abort();this._registeredTurns.clear(),this._turnManager.close(),this._logger?.debug(`DefaultServerTransport.close(); transport closed`)}}_resolveFilter(e,t){let n=[...this._registeredTurns.keys()];return e.all?n:e.own&&t?n.filter(e=>this._registeredTurns.get(e)?.clientId===t):e.clientId?n.filter(t=>this._registeredTurns.get(t)?.clientId===e.clientId):e.turnId&&this._registeredTurns.has(e.turnId)?[e.turnId]:[]}async _handleCancelMessage(e){let n=j(e),r={};n[`x-ably-cancel-turn-id`]?r.turnId=n[v]:n[`x-ably-cancel-own`]===`true`?r.own=!0:n[`x-ably-cancel-client-id`]?r.clientId=n[x]:n[`x-ably-cancel-all`]===`true`&&(r.all=!0);let i=this._resolveFilter(r,e.clientId);if(i.length===0)return;this._logger?.debug(`DefaultServerTransport._handleCancelMessage(); matched turns`,{matchedTurnIds:i,filter:r});let a=new Map;for(let e of i){let t=this._registeredTurns.get(e);a.set(e,t?.clientId??``)}let o={message:e,filter:r,matchedTurnIds:i,turnOwners:a};for(let e of i){let n=this._registeredTurns.get(e);if(n)try{if(n.onCancel&&!await n.onCancel(o)){this._logger?.debug(`DefaultServerTransport._handleCancelMessage(); cancel rejected by onCancel`,{turnId:e});continue}n.controller.abort(),this._logger?.debug(`DefaultServerTransport._handleCancelMessage(); turn aborted`,{turnId:e})}catch(r){let i=new t.ErrorInfo(`unable to process cancel for turn ${e}; onCancel handler threw: ${r instanceof Error?r.message:String(r)}`,k.CancelListenerError,500,r instanceof t.ErrorInfo?r:void 0);this._logger?.error(`DefaultServerTransport._handleCancelMessage(); onCancel threw`,{turnId:e}),(n.onError??this._onError)?.(i)}}}_handleChannelStateChange(e){if(this._state===L.CLOSED)return;let{current:n,resumed:r}=e;if(n===`attached`&&!this._hasAttachedOnce){this._hasAttachedOnce=!0;return}if(!(n===`failed`||n===`suspended`||n===`detached`||n===`attached`&&!r))return;this._logger?.error(`DefaultServerTransport._handleChannelStateChange(); channel continuity lost`,{current:n,resumed:r,previous:e.previous});let i=new t.ErrorInfo(`unable to deliver cancel messages; channel continuity lost (${n}${n===`attached`?`, resumed: false`:``})`,k.ChannelContinuityLost,500,e.reason);this._onError?.(i)}_handleChannelMessage(e){try{e.name===`x-ably-cancel`&&this._handleCancelMessage(e).catch(e=>{let n=new t.ErrorInfo(`unable to route cancel message; ${e instanceof Error?e.message:String(e)}`,k.CancelListenerError,500,e instanceof t.ErrorInfo?e:void 0);this._logger?.error(`DefaultServerTransport._handleChannelMessage(); cancel routing error`),this._onError?.(n)})}catch(e){let n=new t.ErrorInfo(`unable to process channel message; ${e instanceof Error?e.message:String(e)}`,k.TransportSubscriptionError,500,e instanceof t.ErrorInfo?e:void 0);this._logger?.error(`DefaultServerTransport._handleChannelMessage(); subscription error`),this._onError?.(n)}}_createTurn(e){let{turnId:n,clientId:r,onMessage:i,onAbort:a,onCancel:o,onError:s,parent:c,forkOf:l,signal:u}=e,d=new AbortController,f=R.INITIALIZED,p=u?AbortSignal.any([d.signal,u]):d.signal,m={turnId:n,clientId:r??``,controller:d,signal:p,onCancel:o,onError:s};this._registeredTurns.set(n,m);let h=this._logger,g=this._turnManager,_=this._attachPromise,v=this._codec,y=this._channel,b=this._registeredTurns;return{get turnId(){return n},get abortSignal(){return p},start:async()=>{if(h?.trace(`Turn.start();`,{turnId:n}),p.aborted)throw new t.ErrorInfo(`unable to start turn; turn ${n} was cancelled before start()`,k.InvalidArgument,400);if(f===R.INITIALIZED){f=R.STARTED;try{await g.startTurn(n,r,d,{parent:c,forkOf:l})}catch(e){let r=new t.ErrorInfo(`unable to publish turn-start for turn ${n}; ${e instanceof Error?e.message:String(e)}`,k.TurnLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw h?.error(`Turn.start(); failed to publish turn-start`,{turnId:n}),r}h?.debug(`Turn.start(); turn started`,{turnId:n})}},addMessages:async(e,r)=>{if(h?.trace(`Turn.addMessages();`,{turnId:n,count:e.length}),f===R.INITIALIZED)throw new t.ErrorInfo(`unable to add messages; start() must be called before addMessages() (turn ${n})`,k.InvalidArgument,400);await _;let a=[];try{for(let t of e){let e=M(I({role:`user`,turnId:n,msgId:t.msgId,turnClientId:r?.clientId,parent:t.parentId??c,forkOf:t.forkOf??l}),t.headers);await v.createEncoder(y,{extras:{headers:e},onMessage:i}).writeMessages([t.message],r?.clientId?{clientId:r.clientId}:void 0),a.push(t.msgId)}}catch(e){let r=new t.ErrorInfo(`unable to publish messages for turn ${n}; ${e instanceof Error?e.message:String(e)}`,k.TurnLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw h?.error(`Turn.addMessages(); publish failed`,{turnId:n}),r}return h?.debug(`Turn.addMessages(); messages published`,{turnId:n,count:e.length}),{msgIds:a}},addEvents:async e=>{if(h?.trace(`Turn.addEvents();`,{turnId:n,count:e.length}),f===R.INITIALIZED)throw new t.ErrorInfo(`unable to add events; start() must be called before addEvents() (turn ${n})`,k.InvalidArgument,400);await _;let r=g.getClientId(n);try{for(let t of e){let e=I({role:`assistant`,turnId:n,msgId:t.msgId,turnClientId:r,amend:t.msgId}),a=v.createEncoder(y,{extras:{headers:e},onMessage:i});for(let e of t.events)await a.writeEvent(e);await a.close()}}catch(e){let r=new t.ErrorInfo(`unable to publish events for turn ${n}; ${e instanceof Error?e.message:String(e)}`,k.TurnLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw h?.error(`Turn.addEvents(); publish failed`,{turnId:n}),r}h?.debug(`Turn.addEvents(); events published`,{turnId:n,count:e.length})},streamResponse:async(e,r)=>{if(h?.trace(`Turn.streamResponse();`,{turnId:n}),f===R.INITIALIZED)throw new t.ErrorInfo(`unable to stream response; start() must be called before streamResponse() (turn ${n})`,k.InvalidArgument,400);await _;let o=g.getClientId(n),u=r?.parent===void 0?c:r.parent,d=crypto.randomUUID(),m=I({role:`assistant`,turnId:n,msgId:d,turnClientId:o,parent:u,forkOf:r?.forkOf??l}),b=await ae(e,v.createEncoder(y,{extras:{headers:m},onMessage:i,messageId:d}),p,a,r?.resolveWriteOptions,h);if(b.error){let e=new t.ErrorInfo(`unable to stream response for turn ${n}; ${b.error.message}`,k.StreamError,500,b.error instanceof t.ErrorInfo?b.error:void 0);h?.error(`Turn.streamResponse(); stream error`,{turnId:n}),s?.(e)}return h?.debug(`Turn.streamResponse(); stream finished`,{turnId:n,reason:b.reason}),b},end:async e=>{if(h?.trace(`Turn.end();`,{turnId:n,reason:e}),f===R.INITIALIZED)throw new t.ErrorInfo(`unable to end turn; start() must be called before end() (turn ${n})`,k.InvalidArgument,400);if(f!==R.ENDED){f=R.ENDED;try{await g.endTurn(n,e)}catch(e){let r=new t.ErrorInfo(`unable to publish turn-end for turn ${n}; ${e instanceof Error?e.message:String(e)}`,k.TurnLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw h?.error(`Turn.end(); failed to publish turn-end`,{turnId:n}),r}finally{b.delete(n)}h?.debug(`Turn.end(); turn ended`,{turnId:n,reason:e})}}}}},z=e=>new ce(e),B=e=>({logAction:(t,n,r)=>{e.error(n,{detail:r})},shouldLog:()=>!0}),V=t.Realtime.EventEmitter,H=class extends V{constructor(e){super(B(e))}},U=function(e){return e.Trace=`trace`,e.Debug=`debug`,e.Info=`info`,e.Warn=`warn`,e.Error=`error`,e.Silent=`silent`,e}({}),W=(e,t,n)=>{let r=n?`, context: ${JSON.stringify(n)}`:``,i=`[${new Date().toISOString()}] ${t.valueOf().toUpperCase()} ably-ai-transport: ${e}${r}`;switch(t){case U.Trace:case U.Debug:console.log(i);break;case U.Info:console.info(i);break;case U.Warn:console.warn(i);break;case U.Error:console.error(i);break;case U.Silent:break}},G=e=>new le(e.logHandler??W,e.logLevel),K=function(e){return e[e.Trace=0]=`Trace`,e[e.Debug=1]=`Debug`,e[e.Info=2]=`Info`,e[e.Warn=3]=`Warn`,e[e.Error=4]=`Error`,e[e.Silent=5]=`Silent`,e}(K||{}),q=new Map([[U.Trace,K.Trace],[U.Debug,K.Debug],[U.Info,K.Info],[U.Warn,K.Warn],[U.Error,K.Error],[U.Silent,K.Silent]]),le=class e{constructor(e,n,r){this._handler=e,this._context=r;let i=q.get(n);if(i===void 0)throw new t.ErrorInfo(`unable to create logger; invalid log level: ${n}`,k.InvalidArgument,400);this._levelNumber=i}trace(e,t){this._write(e,U.Trace,K.Trace,t)}debug(e,t){this._write(e,U.Debug,K.Debug,t)}info(e,t){this._write(e,U.Info,K.Info,t)}warn(e,t){this._write(e,U.Warn,K.Warn,t)}error(e,t){this._write(e,U.Error,K.Error,t)}withContext(t){let n=[...q.entries()].find(([,e])=>e===this._levelNumber)?.[0]??U.Error;return new e(this._handler,n,this._mergeContext(t))}_write(e,t,n,r){n>=this._levelNumber&&this._handler(e,t,this._mergeContext(r))}_mergeContext(e){return this._context?e?{...this._context,...e}:this._context:e??void 0}},ue=class{constructor(e,t){this._turns=new Map,this._isTerminal=e,this._logger=t}createStream(e){this._logger.trace(`StreamRouter.createStream();`,{turnId:e});let n={},r=new ReadableStream({start(e){n.controller=e}});if(!n.controller)throw new t.ErrorInfo(`unable to create stream; ReadableStream start() was not called synchronously`,k.TransportSubscriptionError,500);return this._turns.set(e,{controller:n.controller,turnId:e}),r}closeStream(e){let t=this._turns.get(e);if(!t)return!1;this._logger.debug(`StreamRouter.closeStream(); closing stream`,{turnId:e});try{t.controller.close()}catch{}return this._turns.delete(e),!0}errorStream(e,t){let n=this._turns.get(e);if(!n)return!1;this._logger.debug(`StreamRouter.errorStream(); erroring stream`,{turnId:e});try{n.controller.error(t)}catch{}return this._turns.delete(e),!0}route(e,t){let n=this._turns.get(e);if(!n)return!1;try{n.controller.enqueue(t)}catch{return this._turns.delete(e),!1}return this._isTerminal(t)&&this.closeStream(e),!0}has(e){return this._turns.has(e)}},de=(e,t)=>new ue(e,t),fe=class{get structuralVersion(){return this._structuralVersion}constructor(e){this._nodeIndex=new Map,this._sortedList=[],this._parentIndex=new Map,this._turnClientIds=new Map,this._seqCounter=0,this._structuralVersion=0,this._logger=e,this._emitter=new H(e)}_compareNodes(e,t){let n=e.node.serial,r=t.node.serial;return n===void 0&&r===void 0?e.insertSeq-t.insertSeq:n===void 0?1:r===void 0||n<r?-1:n>r?1:e.insertSeq-t.insertSeq}_insertSorted(e){if(e.node.serial===void 0){this._sortedList.push(e);return}let t=0,n=this._sortedList.length;for(;t<n;){let r=t+n>>>1,i=this._sortedList[r];if(!i)break;this._compareNodes(i,e)<=0?t=r+1:n=r}this._sortedList.splice(t,0,e)}_removeSorted(e){let t=this._sortedList.indexOf(e);t!==-1&&this._sortedList.splice(t,1)}_addToParentIndex(e,t){let n=this._parentIndex.get(e);n||(n=new Set,this._parentIndex.set(e,n)),n.add(t)}_removeFromParentIndex(e,t){let n=this._parentIndex.get(e);n&&(n.delete(t),n.size===0&&this._parentIndex.delete(e))}_getSiblingGroup(e){let t=this._nodeIndex.get(e);if(!t)return[];let n=t.node,r=new Set([n.msgId]);for(;n.forkOf&&!r.has(n.forkOf);){let e=this._nodeIndex.get(n.forkOf);if(!e||e.node.parentId!==n.parentId)break;n=e.node,r.add(n.msgId)}let i=n.parentId,a=n.msgId,o=[],s=this._parentIndex.get(i);if(s)for(let e of s){let t=this._nodeIndex.get(e);t&&this._isSiblingOf(t.node,a)&&o.push(t)}return o.sort((e,t)=>this._compareNodes(e,t)),o.map(e=>e.node)}_isSiblingOf(e,t){if(e.msgId===t)return!0;let n=e,r=new Set([n.msgId]);for(;n.forkOf;){if(n.forkOf===t)return!0;if(r.has(n.forkOf))break;let e=this._nodeIndex.get(n.forkOf);if(!e)break;n=e.node,r.add(n.msgId)}return!1}getGroupRoot(e){let t=this._nodeIndex.get(e);if(!t)return e;let n=t.node,r=new Set([n.msgId]);for(;n.forkOf&&!r.has(n.forkOf);){let e=this._nodeIndex.get(n.forkOf);if(!e||e.node.parentId!==n.parentId)break;n=e.node,r.add(n.msgId)}return n.msgId}flattenNodes(e){this._logger.trace(`DefaultTree.flattenNodes();`);let t=[],n=new Set,r=new Map;for(let i of this._sortedList){let a=i.node,{msgId:o,parentId:s}=a;if(s!==void 0&&!n.has(s))continue;let c=this._getSiblingGroup(o);if(c.length>1){let t=this.getGroupRoot(o),n=r.get(t);if(n===void 0){let i=e.get(t);if(i&&c.some(e=>e.msgId===i))n=i;else{let e=c.at(-1);if(!e)break;n=e.msgId}r.set(t,n)}if(o!==n)continue}n.add(o),t.push(a)}return t}getSiblings(e){return this._logger.trace(`DefaultTree.getSiblings();`,{msgId:e}),this._getSiblingGroup(e).map(e=>e.message)}getSiblingNodes(e){return this._getSiblingGroup(e)}hasSiblings(e){return this._getSiblingGroup(e).length>1}getNode(e){return this._logger.trace(`DefaultTree.getNode();`,{msgId:e}),this._nodeIndex.get(e)?.node}getHeaders(e){return this._logger.trace(`DefaultTree.getHeaders();`,{msgId:e}),this._nodeIndex.get(e)?.node.headers}upsert(e,t,n,r){let i=n[`x-ably-parent`]??void 0,a=n[`x-ably-fork-of`]??void 0,o=this._nodeIndex.get(e);if(o){o.node.message=t,Object.keys(n).length>0&&(o.node.headers={...n}),r&&!o.node.serial&&(this._logger.debug(`Tree.upsert(); promoting serial`,{msgId:e,serial:r}),o.node.serial=r,this._removeSorted(o),this._insertSorted(o),this._structuralVersion++),this._emitter.emit(`update`);return}this._logger.trace(`Tree.upsert(); inserting new node`,{msgId:e,parentId:i,forkOf:a});let s={node:{kind:`message`,message:t,msgId:e,parentId:i,forkOf:a,headers:{...n},serial:r},insertSeq:this._seqCounter++};this._nodeIndex.set(e,s),this._addToParentIndex(i,e),this._insertSorted(s),this._structuralVersion++,this._emitter.emit(`update`)}delete(e){let t=this._nodeIndex.get(e);if(!t)return;this._logger.debug(`Tree.delete();`,{msgId:e});let{node:n}=t;this._removeFromParentIndex(n.parentId,e),this._removeSorted(t),this._nodeIndex.delete(e),this._structuralVersion++,this._emitter.emit(`update`)}getActiveTurnIds(){this._logger.trace(`DefaultTree.getActiveTurnIds();`);let e=new Map;for(let[t,n]of this._turnClientIds){let r=e.get(n);r||(r=new Set,e.set(n,r)),r.add(t)}return e}on(e,t){let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}emitAblyMessage(e){this._logger.trace(`DefaultTree.emitAblyMessage();`),this._emitter.emit(`ably-message`,e)}emitTurn(e){this._logger.trace(`DefaultTree.emitTurn();`,{turnId:e.turnId}),this._emitter.emit(`turn`,e)}trackTurn(e,t){this._logger.trace(`DefaultTree.trackTurn();`,{turnId:e,clientId:t}),this._turnClientIds.set(e,t)}untrackTurn(e){this._logger.trace(`DefaultTree.untrackTurn();`,{turnId:e}),this._turnClientIds.delete(e)}},pe=e=>new fe(e),me=e=>{let t=[...e.rawMessages].toReversed(),n=e.codec.createDecoder(),r=new Map,i=e.codec.createAccumulator(),a=0,o=new Map,s=new Map,c=[],l=[];for(let u of t){let t=n.decode(u),d=j(u),f=d[p],h=d[m],g=u.serial,v=d[_];if(v){for(let e of r.values())if(e.msgHeaders.has(v)){let n=[...e.msgHeaders.keys()].indexOf(v),r=n===-1?void 0:e.accumulator.messages[n];r&&e.accumulator.initMessage(v,r),e.accumulator.processOutputs(t),l.push({accumulator:e.accumulator,messageId:v});break}continue}if(f){let n=r.get(f);if(n||(n={accumulator:e.codec.createAccumulator(),firstSeen:a++,msgHeaders:new Map,msgSerials:new Map},r.set(f,n)),h){let e=n.msgHeaders.get(h);e?Object.keys(d).length>0&&Object.assign(e,d):(n.msgHeaders.set(h,{...d}),g&&n.msgSerials.set(h,g))}n.accumulator.processOutputs(t)}else{i.processOutputs(t);for(let e of t)if(e.kind===`message`&&h){c.push(h);let e=o.get(h);e?Object.keys(d).length>0&&Object.assign(e,d):(o.set(h,{...d}),g&&s.set(h,g))}}}for(let{accumulator:e,messageId:t}of l)e.completeMessage(t);let u=[];for(let[e,t]of i.completedMessages.entries()){let n=c[e];u.push({message:t,headers:n?o.get(n)??{}:{},serial:n?s.get(n)??``:``})}let d=[...r.values()].toSorted((e,t)=>e.firstSeen-t.firstSeen);for(let e of d){let t=[...e.msgHeaders.entries()],n=0;for(let r of e.accumulator.completedMessages){let i=t[n];if(i){let[t,a]=i;u.push({message:r,headers:a,serial:e.msgSerials.get(t)??``}),n++}else u.push({message:r,headers:{},serial:``})}}return u.toReversed()},he=e=>{if(e.cachedDecode&&e.cachedAtRawLength===e.rawMessages.length)return e.cachedDecode;let t=me(e);return e.cachedDecode=t,e.cachedAtRawLength=e.rawMessages.length,t},J=(e,t)=>{for(let n of t){let t=j(n),r=t[m];if(!r||t[`x-ably-amend`])continue;let i=n.action,a=i===`message.create`&&`x-ably-discrete`in t,o=t[`x-ably-stream`]===`true`&&(i===`message.create`||i===`message.update`||i===`message.append`),s=t[u],c=s===`finished`||s===`aborted`;(a||o)&&e.startedMsgIds.add(r),(a||c)&&e.terminatedMsgIds.add(r),e.startedMsgIds.has(r)&&e.terminatedMsgIds.has(r)&&e.completedMsgIds.add(r)}},Y=async(e,t,n)=>{e.rawMessages.push(...t.items),e.lastAblyPage=t,J(e,t.items);let r=e.returnedCount+n;for(;e.completedMsgIds.size<r&&t.hasNext();){e.logger.debug(`decodeHistory.fetchUntilLimit(); fetching next page`,{collected:e.rawMessages.length,completed:e.completedMsgIds.size});let n=await t.next();if(!n)break;t=n,e.rawMessages.push(...n.items),e.lastAblyPage=n,J(e,n.items)}},X=(e,t)=>{let n=he(e),r=n.slice(e.returnedCount,e.returnedCount+t),i=[...r].toReversed();e.returnedCount+=r.length;let a=n.length>e.returnedCount,o=e.lastAblyPage?.hasNext()??!1,s=e.rawMessages.length-e.returnedRawCount>0?e.rawMessages.slice(e.returnedRawCount).toReversed():[];return e.returnedRawCount=e.rawMessages.length,{items:i.map(e=>({message:e.message,headers:e.headers,serial:e.serial})),rawMessages:s,hasNext:()=>a||o,next:async()=>{if(a)return X(e,t);if(!o||!e.lastAblyPage)return;let n=await e.lastAblyPage.next();if(n)return await Y(e,n,t),X(e,t)}}},ge=async(e,t,n,r)=>{let i=n?.limit??100,a={codec:t,rawMessages:[],returnedCount:0,returnedRawCount:0,lastAblyPage:void 0,cachedDecode:void 0,cachedAtRawLength:0,startedMsgIds:new Set,terminatedMsgIds:new Set,completedMsgIds:new Set,logger:r};r.trace(`decodeHistory();`,{limit:i});let o=i*10;return await e.attach(),await Y(a,await e.history({untilAttach:!0,limit:o}),i),X(a,i)},_e=class{constructor(e){this._branchSelections=new Map,this._withheldMsgIds=new Set,this._lastVisibleIds=[],this._lastVisibleMessages=[],this._lastVisibleTurnIds=new Set,this._hasMoreHistory=!1,this._withheldBuffer=[],this._unsubs=[],this._cachedNodes=[],this._lastStructuralVersion=-1,this._loadingOlder=!1,this._processingHistory=!1,this._closed=!1,this._tree=e.tree,this._channel=e.channel,this._codec=e.codec,this._sendDelegate=e.sendDelegate,this._onClose=e.onClose,this._logger=e.logger.withContext({component:`View`}),this._logger.trace(`DefaultView();`),this._emitter=new H(this._logger),this._cachedNodes=this._computeFlatNodes(),this._lastStructuralVersion=this._tree.structuralVersion,this._updateVisibleSnapshot(this._cachedNodes),this._unsubs.push(this._tree.on(`update`,()=>{this._onTreeUpdate()}),this._tree.on(`ably-message`,e=>{this._onTreeAblyMessage(e)}),this._tree.on(`turn`,e=>{this._onTreeTurn(e)}))}getMessages(){return this.flattenNodes().map(e=>e.message)}flattenNodes(){return this._cachedNodes}_computeFlatNodes(){let e=this._tree.flattenNodes(this._resolveSelections());return this._withheldMsgIds.size===0?e:e.filter(e=>!this._withheldMsgIds.has(e.msgId))}hasOlder(){return this._withheldBuffer.length>0||this._hasMoreHistory}async loadOlder(e=100){if(!(this._closed||this._loadingOlder)){this._loadingOlder=!0,this._logger.trace(`DefaultView.loadOlder();`,{limit:e});try{if(this._withheldBuffer.length>0){let t=this._withheldBuffer.splice(-e,e);this._releaseWithheld(t);return}if(!this._hasMoreHistory&&!this._lastHistoryPage){await this._loadFirstPage(e);return}if(!this._hasMoreHistory)return;if(!this._lastHistoryPage?.hasNext()){this._hasMoreHistory=!1;return}let t=await this._lastHistoryPage.next();if(this._closed||!t){t||(this._hasMoreHistory=!1);return}await this._loadAndReveal(t,e)}catch(e){throw this._logger.error(`DefaultView.loadOlder(); failed`,{error:e}),e}finally{this._loadingOlder=!1}}}select(e,t){this._logger.trace(`DefaultView.select();`,{msgId:e,index:t});let n=this._tree.getSiblingNodes(e);if(n.length<=1)return;let r=this._tree.getGroupRoot(e),i=Math.max(0,Math.min(t,n.length-1)),a=n[i];a&&(this._branchSelections.set(r,{kind:`user`,selectedId:a.msgId}),this._logger.debug(`DefaultView.select();`,{msgId:e,index:i,selectedId:a.msgId}),this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`))}getSelectedIndex(e){this._logger.trace(`DefaultView.getSelectedIndex();`,{msgId:e});let t=this._tree.getSiblingNodes(e);if(t.length<=1)return 0;let n=this._tree.getGroupRoot(e),r=this._branchSelections.get(n);if(!r||r.kind===`pending`)return t.length-1;let i=t.findIndex(e=>e.msgId===r.selectedId);return i===-1?t.length-1:i}getSiblings(e){return this._tree.getSiblings(e)}hasSiblings(e){return this._tree.hasSiblings(e)}getNode(e){return this._tree.getNode(e)}async send(e,n){if(this._logger.trace(`DefaultView.send();`),this._closed)throw new t.ErrorInfo(`unable to send; view is closed`,k.InvalidArgument,400);let r=this.flattenNodes(),i=await this._sendDelegate(e,n,r);if(n?.forkOf){let e=this._tree.getGroupRoot(n.forkOf);if(i.optimisticMsgIds.length>0){let t=i.optimisticMsgIds.at(-1);t&&(this._branchSelections.set(e,{kind:`auto`,selectedId:t}),this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`))}else{this._branchSelections.set(e,{kind:`pending`,turnId:i.turnId}),this._logger.debug(`DefaultView.send(); deferring fork auto-selection`,{forkOf:n.forkOf,groupRoot:e,turnId:i.turnId});let t=this._tree.on(`turn`,n=>{if(n.type!==`x-ably-turn-end`||n.turnId!==i.turnId)return;let r=this._branchSelections.get(e);r?.kind===`pending`&&r.turnId===i.turnId&&this._branchSelections.delete(e),t();let a=this._unsubs.indexOf(t);a!==-1&&this._unsubs.splice(a,1)});this._unsubs.push(t)}}return i}async regenerate(e,n){this._logger.trace(`DefaultView.regenerate();`,{messageId:e});let r=this._tree.getNode(e);if(!r)throw new t.ErrorInfo(`unable to regenerate; message not found in tree: ${e}`,k.InvalidArgument,400);let i=r.parentId;return this.send([],{...n,body:{history:this._getHistoryBefore(e),...n?.body},forkOf:e,parent:i})}async edit(e,n,r){this._logger.trace(`DefaultView.edit();`,{messageId:e});let i=this._tree.getNode(e);if(!i)throw new t.ErrorInfo(`unable to edit; message not found in tree: ${e}`,k.InvalidArgument,400);let a=i.parentId;return this.send(n,{...r,body:{history:this._getHistoryBefore(e),...r?.body},forkOf:e,parent:a})}async update(e,n,r){if(this._closed)throw new t.ErrorInfo(`unable to update; view is closed`,k.InvalidArgument,400);this._logger.trace(`DefaultView.update();`,{msgId:e,eventCount:n.length});let i=[{kind:`event`,msgId:e,events:n}];return this._sendDelegate([],r,this.flattenNodes(),i)}_getHistoryBefore(e){this._logger.trace(`DefaultView._getHistoryBefore();`,{messageId:e});let t=this.flattenNodes(),n=t.findIndex(t=>t.msgId===e);return n===-1?(this._logger.warn(`DefaultView._getHistoryBefore(); target not in visible nodes, returning full list`,{messageId:e}),t):t.slice(0,n)}getActiveTurnIds(){this._logger.trace(`DefaultView.getActiveTurnIds();`);let e=this._tree.getActiveTurnIds();if(this._withheldMsgIds.size===0)return e;let t=new Map;for(let[n,r]of e){let e=new Set;for(let t of r)this._lastVisibleTurnIds.has(t)&&e.add(t);e.size>0&&t.set(n,e)}return t}on(e,t){let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}close(){this._logger.info(`DefaultView.close();`),this._closed=!0,this._loadingOlder=!1;for(let e of this._unsubs)e();this._unsubs.length=0,this._emitter.off(),this._branchSelections.clear(),this._withheldMsgIds.clear(),this._withheldBuffer.length=0,this._onClose?.()}async _loadFirstPage(e){let t=new Set(this._tree.flattenNodes(this._resolveSelections()).map(e=>e.msgId)),n=await ge(this._channel,this._codec,{limit:e},this._logger);if(this._closed)return;let{newVisible:r,lastPage:i}=await this._loadUntilVisible(n,e,t);if(this._closed)return;this._lastHistoryPage=i,this._hasMoreHistory=i.hasNext();let a=r.slice(-e),o=r.slice(0,-e);for(let e of o)this._withheldMsgIds.add(e.msgId);this._withheldBuffer.push(...o),this._releaseWithheld(a)}async _loadAndReveal(e,t){let n=new Set(this._tree.flattenNodes(this._resolveSelections()).map(e=>e.msgId)),{newVisible:r,lastPage:i}=await this._loadUntilVisible(e,t,n);if(this._closed)return;this._lastHistoryPage=i,this._hasMoreHistory=i.hasNext();let a=r.slice(-t),o=r.slice(0,-t);for(let e of o)this._withheldMsgIds.add(e.msgId);this._withheldBuffer.push(...o),this._releaseWithheld(a)}_processHistoryPage(e){this._processingHistory=!0;try{for(let t of e.items){let e=t.headers[m];e&&this._tree.upsert(e,t.message,t.headers,t.serial)}for(let t of e.rawMessages)this._tree.emitAblyMessage(t)}finally{this._processingHistory=!1}}async _loadUntilVisible(e,t,n){this._processHistoryPage(e);let r=e,i=()=>{let e=0;for(let t of this._tree.flattenNodes(this._resolveSelections()))n.has(t.msgId)||e++;return e};for(;i()<t&&r.hasNext();){let e=await r.next();if(!e||this._closed)break;this._processHistoryPage(e),r=e}return{newVisible:this._tree.flattenNodes(this._resolveSelections()).filter(e=>!n.has(e.msgId)),lastPage:r}}_releaseWithheld(e){for(let t of e)this._withheldMsgIds.delete(t.msgId);e.length>0&&(this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`))}_updateVisibleSnapshot(e){let t=e??this.flattenNodes();this._lastVisibleIds=t.map(e=>e.msgId),this._lastVisibleMessages=t.map(e=>e.message),this._lastVisibleTurnIds=new Set;for(let e of t){let t=e.headers[p];t&&this._lastVisibleTurnIds.add(t)}}_onTreeUpdate(){if(this._processingHistory)return;let e=this._tree.structuralVersion;if(e===this._lastStructuralVersion){this._cachedNodes.some((e,t)=>e.message!==this._lastVisibleMessages[t])&&(this._lastVisibleMessages=this._cachedNodes.map(e=>e.message),this._cachedNodes=[...this._cachedNodes],this._emitter.emit(`update`));return}this._lastStructuralVersion=e,this._pinBranchSelections(),this._resolvePendingSelections();let t=this._computeFlatNodes(),n=t.map(e=>e.msgId),r=t.map(e=>e.message);this._visibleChanged(n,r)&&(this._cachedNodes=t,this._updateVisibleSnapshot(t),this._emitter.emit(`update`))}_resolveSelections(){let e=new Map;for(let[t,n]of this._branchSelections)n.kind!==`pending`&&e.set(t,n.selectedId);return e}_pinBranchSelections(){for(let e of this._lastVisibleIds){if(!this._tree.hasSiblings(e))continue;let t=this._tree.getGroupRoot(e),n=this._branchSelections.get(t);if(n?.kind===`pending`){let r=this._tree.getSiblingNodes(e).at(-1);r&&r.msgId!==e&&r.headers[`x-ably-turn-id`]===n.turnId&&(this._logger.debug(`DefaultView._pinBranchSelections(); auto-selecting pending fork`,{msgId:e,newestId:r.msgId,turnId:n.turnId}),this._branchSelections.set(t,{kind:`auto`,selectedId:r.msgId}));continue}n||this._branchSelections.set(t,{kind:`pinned`,selectedId:e})}}_resolvePendingSelections(){for(let[e,t]of this._branchSelections){if(t.kind!==`pending`)continue;let n=this._tree.getSiblingNodes(e);if(n.length<=1)continue;let r=n.at(-1);!r||r.msgId===e||r.headers[`x-ably-turn-id`]===t.turnId&&(this._logger.debug(`DefaultView._resolvePendingSelections(); resolving off-branch pending`,{groupRoot:e,newestId:r.msgId,turnId:t.turnId}),this._branchSelections.set(e,{kind:`auto`,selectedId:r.msgId}))}}_onTreeAblyMessage(e){let t=j(e)[m];if(!t){this._emitter.emit(`ably-message`,e);return}this._lastVisibleIds.includes(t)&&this._emitter.emit(`ably-message`,e)}_onTreeTurn(e){if(this._lastVisibleTurnIds.has(e.turnId)){this._emitter.emit(`turn`,e);return}e.type===`x-ably-turn-start`&&this._isTurnStartVisible(e)&&(this._lastVisibleTurnIds.add(e.turnId),this._emitter.emit(`turn`,e))}_isTurnStartVisible(e){let{parent:t}=e;return t===void 0?!0:this._lastVisibleIds.includes(t)}_visibleChanged(e,t){if(e.length!==this._lastVisibleIds.length)return!0;for(let[t,n]of e.entries())if(n!==this._lastVisibleIds[t])return!0;for(let[e,n]of t.entries())if(n!==this._lastVisibleMessages[e])return!0;return!1}},Z=e=>new _e(e),ve=()=>{},Q=function(e){return e.READY=`ready`,e.CLOSED=`closed`,e}(Q||{}),ye=class{constructor(e){if(this._ownMsgIds=new Set,this._ownTurnIds=new Set,this._turnMsgIds=new Map,this._turnObservers=new Map,this._closeResolvers=[],this._views=new Set,this._state=Q.READY,this._pendingLocalEvents=[],this._channel=e.channel,this._codec=e.codec,this._clientId=e.clientId,this._api=e.api,this._credentials=e.credentials,this._headersFn=typeof e.headers==`function`?e.headers:e.headers?()=>e.headers:void 0,this._bodyFn=typeof e.body==`function`?e.body:e.body?()=>e.body:void 0,this._fetchFn=e.fetch??globalThis.fetch.bind(globalThis),this._logger=(e.logger??G({logLevel:U.Silent})).withContext({component:`ClientTransport`}),this._emitter=new H(this._logger),this._hasAttachedOnce=this._channel.state===`attached`,this._tree=pe(this._logger),this._view=Z({tree:this._tree,channel:this._channel,codec:this._codec,sendDelegate:this._internalSend.bind(this),logger:this._logger,onClose:()=>this._views.delete(this._view)}),this._router=de(this._codec.isTerminal.bind(this._codec),this._logger),this._decoder=this._codec.createDecoder(),this._views.add(this._view),this.tree=this._tree,this.view=this._view,e.messages){let t;for(let n of e.messages){let e=crypto.randomUUID(),r={[m]:e};t&&(r[S]=t),this._tree.upsert(e,n,r),t=e}}this._onMessage=e=>{this._handleMessage(e)},this._attachPromise=this._channel.subscribe(this._onMessage),this._onChannelStateChange=e=>{this._handleChannelStateChange(e)},this._channel.on(this._onChannelStateChange)}_handleMessage(e){if(this._state!==Q.CLOSED)try{if(e.name===`x-ably-turn-start`){let t=j(e),n=t[p],r=t[`x-ably-turn-client-id`]??``;if(n){this._tree.trackTurn(n,r);let e=t[S],i=t[C];this._tree.emitTurn({type:E,turnId:n,clientId:r,...e!==void 0&&{parent:e},...i!==void 0&&{forkOf:i}})}this._tree.emitAblyMessage(e);return}if(e.name===`x-ably-turn-end`){let t=j(e),n=t[p],r=t[`x-ably-turn-client-id`]??``,i=t[`x-ably-turn-reason`]??`complete`;if(n){this._router.closeStream(n),this._turnObservers.delete(n),this._tree.untrackTurn(n);let e=this._turnMsgIds.get(n);if(e){for(let t of e)this._ownMsgIds.delete(t);this._turnMsgIds.delete(n)}this._ownTurnIds.delete(n),this._tree.emitTurn({type:D,turnId:n,clientId:r,reason:i})}this._tree.emitAblyMessage(e);return}let t=this._decoder.decode(e),n=j(e),r=e.serial,i=n[_];if(i){for(let e of t)e.kind===`event`&&this._handleAmendmentEvent(i,e);return}let a=n[p];a&&this._updateTurnObserverHeaders(a,n,r);for(let i of t)i.kind===`message`?this._handleMessageOutput(i.message,n,r,e.action):this._handleEventOutput(i,n);this._tree.emitAblyMessage(e)}catch(e){let n=e instanceof t.ErrorInfo?e:void 0;this._emitter.emit(`error`,new t.ErrorInfo(`unable to process channel message; ${e instanceof Error?e.message:String(e)}`,k.TransportSubscriptionError,500,n))}}_handleMessageOutput(e,t,n,r){let i=t[m];if(i&&this._ownMsgIds.has(i)){this._upsertAndNotify(e,t,n);return}r===`message.create`&&this._upsertAndNotify(e,t,n)}_handleEventOutput(e,t){if(e.kind!==`event`)return;let n=e.event,r=t[p];if(r){if(this._router.route(r,n)){this._accumulateAndEmit(r,e),this._codec.isTerminal(n)&&this._turnObservers.delete(r);return}this._ownTurnIds.has(r)&&!this._turnObservers.has(r)||(this._accumulateAndEmit(r,e),this._codec.isTerminal(n)&&this._turnObservers.delete(r))}}_handleAmendmentEvent(e,t){this._logger.trace(`ClientTransport._handleAmendmentEvent();`,{targetMsgId:e});let n=this._tree.getNode(e);if(!n){this._logger.debug(`ClientTransport._handleAmendmentEvent(); target not found, dropping`,{targetMsgId:e});return}let r=this._codec.createAccumulator();r.initMessage(e,n.message),r.processOutputs([t]);let i=r.messages.at(-1);i&&this._tree.upsert(e,i,n.headers,n.serial)}_handleChannelStateChange(e){if(this._state===Q.CLOSED)return;let{current:n,resumed:r}=e;if(n===`attached`&&!this._hasAttachedOnce){this._hasAttachedOnce=!0;return}if(!(n===`failed`||n===`suspended`||n===`detached`||n===`attached`&&!r))return;this._logger.error(`ClientTransport._handleChannelStateChange(); channel continuity lost`,{current:n,resumed:r,previous:e.previous});let i=new t.ErrorInfo(`unable to deliver events; channel continuity lost (${n}${n===`attached`?`, resumed: false`:``})`,k.ChannelContinuityLost,500,e.reason);for(let e of this._ownTurnIds)this._router.errorStream(e,i);this._emitter.emit(`error`,i)}_upsertAndNotify(e,t,n){let r=t[m];r&&this._tree.upsert(r,e,t,n)}_updateTurnObserverHeaders(e,t,n){let r=this._turnObservers.get(e);r?(Object.keys(t).length>0&&Object.assign(r.headers,t),n!==void 0&&(r.serial=n)):this._turnObservers.set(e,{headers:{...t},serial:n,accumulator:this._codec.createAccumulator()})}_accumulateAndEmit(e,t){let n=this._turnObservers.get(e);if(!n)return;let r=n.headers[m];if(r){let e=this._tree.getNode(r);e&&n.accumulator.initMessage(r,e.message)}n.accumulator.processOutputs([t]);let i=n.accumulator.messages;if(i.length===0)return;let a;try{a=structuredClone(i.at(-1))}catch{a=i.at(-1)}if(a){let e=n.headers[m];e&&this._tree.upsert(e,a,{...n.headers},n.serial)}}async _publishCancel(e){this._logger.trace(`ClientTransport._publishCancel();`,{filter:e});let t={};e.turnId?t[v]=e.turnId:e.own?t[y]=`true`:e.clientId?t[x]=e.clientId:e.all&&(t[b]=`true`),await this._channel.publish({name:T,extras:{headers:t}})}_closeMatchingTurnStreams(e){for(let t of this._getMatchingTurnIds(e))this._router.closeStream(t)}_getMatchingTurnIds(e){let t=new Set,n=this._tree.getActiveTurnIds();if(e.all)for(let e of n.values())for(let n of e)t.add(n);else if(e.own){let e=n.get(this._clientId??``);if(e)for(let n of e)t.add(n)}else if(e.clientId){let r=n.get(e.clientId);if(r)for(let e of r)t.add(e)}else if(e.turnId){for(let r of n.values())if(r.has(e.turnId)){t.add(e.turnId);break}}return t}createView(){if(this._state===Q.CLOSED)throw new t.ErrorInfo(`unable to create view; transport is closed`,k.TransportClosed,400);this._logger.trace(`DefaultClientTransport.createView();`);let e=Z({tree:this._tree,channel:this._channel,codec:this._codec,sendDelegate:this._internalSend.bind(this),logger:this._logger,onClose:()=>this._views.delete(e)});return this._views.add(e),e}async _internalSend(e,n,r,i){if(this._state===Q.CLOSED||(await this._attachPromise,this._state===Q.CLOSED))throw new t.ErrorInfo(`unable to send; transport is closed`,k.TransportClosed,400);let a=this._channel.state;if(a!==`attached`&&a!==`attaching`)throw new t.ErrorInfo(`unable to send; channel is ${a}`,k.ChannelNotReady,400);this._logger.trace(`ClientTransport._internalSend();`);let o=Array.isArray(e)?e:[e],s=crypto.randomUUID();this._ownTurnIds.add(s),this._tree.trackTurn(s,this._clientId??``);let c=this._pendingLocalEvents;this._pendingLocalEvents=[],i&&i.length>0&&this._applyEventsToTree(i);let l=[...c,...i??[]],u=new Set,d=[],f=r,p;if(n?.parent===void 0&&!n?.forkOf){let e=f.at(-1);e&&(p=e.msgId)}let m=n?.parent===void 0?p:n.parent;for(let e of o){let t=crypto.randomUUID();this._ownMsgIds.add(t),u.add(t);let r=n?.parent===void 0?p:n.parent,i=I({role:`user`,turnId:s,msgId:t,turnClientId:this._clientId,parent:r,forkOf:n?.forkOf});this._upsertAndNotify(e,i),d.push({kind:`message`,message:e,msgId:t,parentId:r,forkOf:n?.forkOf,headers:i,serial:void 0}),n?.parent===void 0&&!n?.forkOf&&(p=t)}this._turnMsgIds.set(s,u);let h=this._router.createStream(s),g=this._headersFn?.()??{},_={...this._bodyFn?.()??{},history:f,...n?.body,turnId:s,clientId:this._clientId,messages:d,...n?.forkOf!==void 0&&{forkOf:n.forkOf},...m!==void 0&&{parent:m},...l.length>0&&{events:l}},v={...g,...n?.headers};return this._fetchFn(this._api,{method:`POST`,headers:{"Content-Type":`application/json`,...v},body:JSON.stringify(_),...this._credentials?{credentials:this._credentials}:{}}).then(e=>{if(!e.ok){let n=new t.ErrorInfo(`unable to send; HTTP POST to ${this._api} returned ${String(e.status)} ${e.statusText}`,k.TransportSendFailed,e.status);this._emitter.emit(`error`,n),this._router.errorStream(s,n)}}).catch(e=>{let n=e instanceof t.ErrorInfo?e:void 0,r=new t.ErrorInfo(`unable to send; HTTP POST to ${this._api} failed: ${e instanceof Error?e.message:String(e)}`,k.TransportSendFailed,500,n);this._emitter.emit(`error`,r),this._router.errorStream(s,r)}),{stream:h,turnId:s,cancel:async()=>this.cancel({turnId:s}),optimisticMsgIds:[...u]}}async cancel(e){if(this._state===Q.CLOSED)return;let t=e??{own:!0};this._logger.debug(`ClientTransport.cancel();`,{filter:t}),await this._publishCancel(t),this._closeMatchingTurnStreams(t)}stageEvents(e,t){if(this._logger.trace(`ClientTransport.stageEvents();`,{msgId:e,eventCount:t.length}),this._state===Q.CLOSED){this._logger.warn(`ClientTransport.stageEvents(); transport is closed`,{msgId:e});return}if(!this._tree.getNode(e)){this._logger.warn(`ClientTransport.stageEvents(); msgId not found in tree`,{msgId:e});return}if(t.length===0)return;let n={kind:`event`,msgId:e,events:t};this._applyEventsToTree([n]),this._pendingLocalEvents.push(n)}stageMessage(e,t){if(this._logger.trace(`ClientTransport.stageMessage();`,{msgId:e}),this._state===Q.CLOSED){this._logger.warn(`ClientTransport.stageMessage(); transport is closed`,{msgId:e});return}let n=this._tree.getNode(e);if(!n){this._logger.warn(`ClientTransport.stageMessage(); msgId not found in tree`,{msgId:e});return}this._tree.upsert(e,t,n.headers,n.serial)}_applyEventsToTree(e){for(let t of e){let e=this._tree.getNode(t.msgId);if(!e)continue;let n=t.events.map(e=>({kind:`event`,event:e,messageId:t.msgId})),r=this._codec.createAccumulator();r.initMessage(t.msgId,e.message),r.processOutputs(n);let i=r.messages.at(-1);i&&this._tree.upsert(t.msgId,i,e.headers,e.serial)}}async waitForTurn(e){if(this._state===Q.CLOSED)return;let t=e??{own:!0},n=this._getMatchingTurnIds(t);if(n.size!==0)return this._logger.debug(`ClientTransport.waitForTurn();`,{turnIds:[...n]}),new Promise(e=>{let t=!1,r=()=>{if(t)return;t=!0,i();let n=this._closeResolvers.indexOf(r);n!==-1&&this._closeResolvers.splice(n,1),e()},i=this._tree.on(`turn`,e=>{e.type===`x-ably-turn-end`&&(n.delete(e.turnId),n.size===0&&r())});this._closeResolvers.push(r)})}on(e,t){if(this._state===Q.CLOSED)return ve;let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}async close(e){if(this._state!==Q.CLOSED){if(this._state=Q.CLOSED,this._logger.info(`ClientTransport.close();`),e?.cancel){try{await this._publishCancel(e.cancel)}catch{}this._closeMatchingTurnStreams(e.cancel)}this._channel.unsubscribe(this._onMessage),this._channel.off(this._onChannelStateChange);for(let e of this._ownTurnIds)this._router.closeStream(e);this._turnObservers.clear(),this._emitter.off();for(let e of this._views)e.close();this._views.clear();for(let e of this._closeResolvers)e();this._closeResolvers.length=0,this._ownTurnIds.clear(),this._ownMsgIds.clear(),this._turnMsgIds.clear()}}},be=e=>new ye(e),$=e=>[{kind:`event`,event:e}],xe=class{constructor(e,t={}){this._serialState=new Map,this._hooks=e,this._onStreamUpdate=t.onStreamUpdate,this._onStreamDelete=t.onStreamDelete,this._logger=t.logger?.withContext({component:`DecoderCore`})}decode(e){let t=e.action;this._logger?.trace(`DefaultDecoderCore.decode();`,{action:t,serial:e.serial,name:e.name});let n;switch(t){case`message.create`:{let t=this._toPayload(e);n=t.headers?.[`x-ably-stream`]===`true`?this._decodeStreamedCreate(t,e.serial):this._hooks.decodeDiscrete(t);break}case`message.append`:n=this._decodeAppend(e);break;case`message.update`:n=this._decodeUpdate(e);break;case`message.delete`:n=this._decodeDelete(e);break;default:return[]}let r=j(e)[m];if(r)for(let e of n)e.kind===`event`&&(e.messageId=r);return n}_toPayload(e){return{name:e.name??``,data:e.data,headers:j(e)}}_stringData(e){return typeof e.data==`string`?e.data:``}_invokeOnStreamUpdate(e){if(this._onStreamUpdate)try{this._onStreamUpdate(e)}catch(e){this._logger?.error(`DefaultDecoderCore._invokeOnStreamUpdate(); callback threw`,{error:e})}}_invokeOnStreamDelete(e,t){if(this._onStreamDelete)try{this._onStreamDelete(e,t)}catch(e){this._logger?.error(`DefaultDecoderCore._invokeOnStreamDelete(); callback threw`,{error:e})}}_decodeStreamedCreate(e,t){if(!t)return[];let n=e.headers?.[`x-ably-stream-id`]??``,r=e.headers??{},i={name:e.name,streamId:n,accumulated:``,headers:{...r},closed:!1};return this._serialState.set(t,i),this._logger?.debug(`DefaultDecoderCore._decodeStreamedCreate(); new stream`,{name:e.name,streamId:n,serial:t}),this._hooks.buildStartEvents(i)}_decodeAppend(e){let t=e.serial;if(!t)return[];let n=this._serialState.get(t);if(!n)return this._decodeUpdate(e);let r=j(e),i=typeof e.data==`string`?e.data:``,a=r[u],o=[];return i.length>0&&(n.accumulated+=i,o.push(...this._hooks.buildDeltaEvents(n,i))),a===`finished`&&!n.closed?(n.closed=!0,o.push(...this._hooks.buildEndEvents(n,r)),this._logger?.debug(`DefaultDecoderCore._decodeAppend(); stream finished`,{streamId:n.streamId})):a===`aborted`&&!n.closed&&(n.closed=!0,this._logger?.debug(`DefaultDecoderCore._decodeAppend(); stream aborted`,{streamId:n.streamId})),o}_decodeUpdate(e){let t=e.serial;if(!t)return[];let n=this._toPayload(e),r=n.headers??{},i=r[l]===`true`,a=r[u],o=this._serialState.get(t);if(!o)return this._decodeFirstContact(n,i,a,t);let s=this._stringData(e);if(s.startsWith(o.accumulated)){let e=s.slice(o.accumulated.length),t=[];return e.length>0&&(o.accumulated=s,t.push(...this._hooks.buildDeltaEvents(o,e))),a===`finished`&&!o.closed?(o.closed=!0,t.push(...this._hooks.buildEndEvents(o,r))):a===`aborted`&&!o.closed&&(o.closed=!0),t}return o.accumulated=s,o.headers={...r},this._invokeOnStreamUpdate(o),[]}_decodeFirstContact(e,t,n,r){if(!t)return this._hooks.decodeDiscrete(e);let i=e.headers?.[`x-ably-stream-id`]??``,a=e.headers??{},o=typeof e.data==`string`?e.data:``;this._logger?.debug(`DefaultDecoderCore._decodeFirstContact(); first-contact stream`,{name:e.name,streamId:i,serial:r});let s={name:e.name,streamId:i,accumulated:o,headers:{...a},closed:n===`finished`||n===`aborted`};this._serialState.set(r,s);let c=this._hooks.buildStartEvents(s);return o.length>0&&c.push(...this._hooks.buildDeltaEvents(s,o)),n===`finished`&&c.push(...this._hooks.buildEndEvents(s,a)),c}_decodeDelete(e){let t=e.serial;if(!t)return[];let n=this._serialState.get(t);return this._invokeOnStreamDelete(t,n),n&&(n.accumulated=``,n.closed=!0),this._logger?.debug(`DefaultDecoderCore._decodeDelete();`,{serial:t}),[]}},Se=(e,t={})=>new xe(e,t),Ce=class{constructor(e,t={}){this._trackers=new Map,this._pending=[],this._closed=!1,this._writer=e,this._defaultClientId=t.clientId,this._defaultExtras=t.extras,this._onMessageHook=t.onMessage??(()=>{}),this._logger=t.logger?.withContext({component:`EncoderCore`})}async publishDiscrete(e,t){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.publishDiscrete();`,{name:e.name});let n=this._buildDiscreteMessage(e,t);return this._writer.publish(n)}async publishDiscreteBatch(e,t){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.publishDiscreteBatch();`,{count:e.length});let n=e.map(e=>this._buildDiscreteMessage(e,t));for(let e of n)e.extras.headers[f]=`true`;return this._writer.publish(n)}async startStream(e,n,r){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.startStream();`,{name:n.name,streamId:e});let i=this._buildHeaders(n.headers??{},r);i[l]=`true`,i[u]=`streaming`,i[d]=e;let a=this._resolveClientId(r),o={name:n.name,data:n.data,extras:{headers:i},...a?{clientId:a}:{}};this._invokeOnMessage(o);let s=(await this._writer.publish(o)).serials[0];if(!s)throw new t.ErrorInfo(`unable to start stream; no serial returned for stream '${n.name}' (streamId: ${e})`,k.BadRequest,400);this._trackers.set(e,{serial:s,name:n.name,streamId:e,accumulated:n.data,persistentHeaders:i,aborted:!1}),this._logger?.debug(`DefaultEncoderCore.startStream(); stream started`,{name:n.name,streamId:e,serial:s})}appendStream(e,n){this._assertNotClosed();let r=this._trackers.get(e);if(!r)throw new t.ErrorInfo(`unable to append to stream; no active stream for streamId '${e}'`,k.InvalidArgument,400);r.accumulated+=n;let i={serial:r.serial,data:n,extras:{headers:{...r.persistentHeaders}}};this._invokeOnMessage(i);let a=this._writer.appendMessage(i);this._pending.push({promise:a,streamId:e})}async closeStream(e,n){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.closeStream();`,{streamId:e});let r=this._trackers.get(e);if(!r)throw new t.ErrorInfo(`unable to close stream; no active stream for streamId '${e}'`,k.InvalidArgument,400);r.accumulated+=n.data;let i=this._buildClosingHeaders(r,n.headers??{});i[u]=`finished`;let a={serial:r.serial,data:n.data,extras:{headers:i}};this._invokeOnMessage(a);let o=this._writer.appendMessage(a);this._pending.push({promise:o,streamId:e}),await this._flushPending(),this._logger?.debug(`DefaultEncoderCore.closeStream(); stream closed`,{streamId:e})}async abortStream(e,n){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.abortStream();`,{streamId:e});let r=this._trackers.get(e);if(!r)throw new t.ErrorInfo(`unable to abort stream; no active stream for streamId '${e}'`,k.InvalidArgument,400);r.aborted=!0;let i=this._buildClosingHeaders(r,{},n);i[u]=`aborted`;let a={serial:r.serial,data:``,extras:{headers:i}};this._invokeOnMessage(a);let o=this._writer.appendMessage(a);this._pending.push({promise:o,streamId:e}),await this._flushPending(),this._logger?.debug(`DefaultEncoderCore.abortStream(); stream aborted`,{streamId:e})}async abortAllStreams(e){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.abortAllStreams();`,{streamCount:this._trackers.size});for(let t of this._trackers.values()){t.aborted=!0;let n=this._buildClosingHeaders(t,{},e);n[u]=`aborted`;let r={serial:t.serial,data:``,extras:{headers:n}};this._invokeOnMessage(r);let i=this._writer.appendMessage(r);this._pending.push({promise:i,streamId:t.streamId})}await this._flushPending()}async _flushPending(){if(this._flushPromise)return this._flushPromise;let e=this._pending;if(this._pending=[],e.length!==0){this._logger?.trace(`DefaultEncoderCore._flushPending();`,{count:e.length}),this._flushPromise=this._doFlush(e);try{await this._flushPromise}finally{this._flushPromise=void 0}}}async _doFlush(e){let n=await Promise.allSettled(e.map(async e=>e.promise)),r=new Set;for(let[t,i]of n.entries()){let n=e[t];n&&i.status===`rejected`&&r.add(n.streamId)}if(r.size===0){this._logger?.debug(`DefaultEncoderCore._flushPending(); all appends succeeded`);return}this._logger?.warn(`DefaultEncoderCore._flushPending(); recovering failed appends`,{failedStreams:[...r]});let i=[];for(let e of r){let t=this._trackers.get(e);if(!t)continue;let n=t.aborted?`aborted`:`finished`,r={serial:t.serial,data:t.accumulated,extras:{headers:{...t.persistentHeaders,[u]:n}}};try{await this._writer.updateMessage(r)}catch(t){i.push({streamId:e,error:t})}}if(i.length>0){let e=i.map(e=>e.streamId).join(`, `);throw this._logger?.error(`DefaultEncoderCore._flushPending(); recovery failed`,{failedStreams:e}),new t.ErrorInfo(`unable to flush pending appends; recovery failed for stream(s): ${e}`,k.EncoderRecoveryFailed,500)}}async close(){if(!this._closed){this._logger?.trace(`DefaultEncoderCore.close();`),this._closed=!0;try{await this._flushPending()}finally{this._trackers.clear()}this._logger?.debug(`DefaultEncoderCore.close(); encoder closed`)}}_invokeOnMessage(e){try{this._onMessageHook(e)}catch(e){this._logger?.error(`DefaultEncoderCore._invokeOnMessage(); hook threw`,{error:e})}}_assertNotClosed(){if(this._closed)throw new t.ErrorInfo(`unable to write to encoder; encoder has been closed`,k.InvalidArgument,400)}_resolveClientId(e){return e?.clientId??this._defaultClientId}_buildHeaders(e,t){let n={...M(this._defaultExtras?.headers,t?.extras?.headers),...e};return t?.messageId!==void 0&&(n[m]=t.messageId),n}_buildDiscreteMessage(e,t){let n=this._buildHeaders(e.headers??{},t);n[l]=`false`;let r=this._resolveClientId(t),i={name:e.name,data:e.data,extras:{headers:n,...e.ephemeral?{ephemeral:!0}:{}},...r?{clientId:r}:{}};return this._invokeOnMessage(i),i}_buildClosingHeaders(e,t,n){let r={...e.persistentHeaders},i=M(this._defaultExtras?.headers,n?.extras?.headers);return Object.assign(r,i),Object.assign(r,t),r}},we=(e,t={})=>new Ce(e,t),Te=class{constructor(e){this._emitted=new Map,this._phases=e}ensurePhases(e,t){let n=this._getOrCreate(e),r=[];for(let e of this._phases)n.has(e.key)||(n.add(e.key),r.push(...e.build(t)));return r}markEmitted(e,t){this._getOrCreate(e).add(t)}resetPhase(e,t){this._emitted.get(e)?.delete(t)}clearScope(e){this._emitted.delete(e)}_getOrCreate(e){let t=this._emitted.get(e);return t||(t=new Set,this._emitted.set(e,t)),t}};e.DOMAIN_HEADER_PREFIX=O,e.EVENT_ABORT=ee,e.EVENT_CANCEL=T,e.EVENT_ERROR=te,e.EVENT_TURN_END=D,e.EVENT_TURN_START=E,e.ErrorCode=k,e.EventEmitter=H,e.HEADER_CANCEL_ALL=b,e.HEADER_CANCEL_CLIENT_ID=x,e.HEADER_CANCEL_OWN=y,e.HEADER_CANCEL_TURN_ID=v,e.HEADER_FORK_OF=C,e.HEADER_MSG_ID=m,e.HEADER_PARENT=S,e.HEADER_ROLE=g,e.HEADER_STATUS=u,e.HEADER_STREAM=l,e.HEADER_STREAM_ID=d,e.HEADER_TURN_CLIENT_ID=h,e.HEADER_TURN_ID=p,e.HEADER_TURN_REASON=w,e.LogLevel=U,e.buildTransportHeaders=I,e.consoleLogger=W,e.createClientTransport=be,e.createDecoderCore=Se,e.createEncoderCore=we,e.createLifecycleTracker=e=>new Te(e),e.createServerTransport=z,e.errorInfoIs=A,e.eventOutput=$,e.getHeaders=j,e.headerReader=re,e.headerWriter=ie,e.makeLogger=G,e.mergeHeaders=M,e.stripUndefined=F});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`ably`)):typeof define==`function`&&define.amd?define([`exports`,`ably`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.AblyAiTransport={},e.Ably))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.create,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,c=(e,t,n,o)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=a(t),l=0,u=c.length,d;l<u;l++)d=c[l],!s.call(e,d)&&d!==n&&r(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(o=i(t,d))||o.enumerable});return e};t=((e,t,i)=>(i=e==null?{}:n(o(e)),c(t||!e||!e.__esModule?r(i,`default`,{value:e,enumerable:!0}):i,e)))(t,1);var l=class e{constructor(e){this.inputEventId=e.inputEventId,this.sessionName=e.sessionName}static fromJSON(t){return new e(t)}toJSON(){return{inputEventId:this.inputEventId,sessionName:this.sessionName}}},u=`stream`,d=`status`,f=`stream-id`,p=`discrete`,m=`run-id`,h=`invocation-id`,g=`event-id`,_=`codec-message-id`,v=`run-client-id`,y=`input-client-id`,b=`role`,x=`parent`,S=`fork-of`,C=`msg-regenerate`,w=`run-reason`,T=`input-codec-message-id`,E=`error-code`,ee=`error-message`,D=`ai-cancel`,O=`ai-run-start`,te=`ai-run-suspend`,k=`ai-run-resume`,A=`ai-run-end`,j=function(e){return e[e.BadRequest=4e4]=`BadRequest`,e[e.InvalidArgument=40003]=`InvalidArgument`,e[e.InsufficientCapability=40160]=`InsufficientCapability`,e[e.EncoderRecoveryFailed=104e3]=`EncoderRecoveryFailed`,e[e.SessionSubscriptionError=104001]=`SessionSubscriptionError`,e[e.CancelListenerError=104002]=`CancelListenerError`,e[e.RunLifecycleError=104003]=`RunLifecycleError`,e[e.SessionClosed=104004]=`SessionClosed`,e[e.SessionSendFailed=104005]=`SessionSendFailed`,e[e.ChannelContinuityLost=104006]=`ChannelContinuityLost`,e[e.ChannelNotReady=104007]=`ChannelNotReady`,e[e.StreamError=104008]=`StreamError`,e[e.InputEventNotFound=104010]=`InputEventNotFound`,e}({}),ne=(e,t)=>e.code===t,M=(e,t)=>{let n=e.extras;if(!n||typeof n!=`object`)return{};let r=n.ai;if(!r||typeof r!=`object`)return{};let i=r[t];return!i||typeof i!=`object`?{}:i},N=e=>M(e,`transport`),P=e=>M(e,`codec`),F=e=>{if(e!==void 0)try{return JSON.parse(e)}catch{return}},I=(e,t)=>({...e,...t}),L=e=>{if(e!==void 0)return e===`true`},R=(e,t)=>e.serial===void 0&&t.serial===void 0?0:e.serial===void 0?1:t.serial===void 0||e.serial<t.serial?-1:+(e.serial>t.serial),z=(e,t)=>e[t],B=e=>{let t={};for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&e[n]!==void 0&&(t[n]=e[n]);return t},V=e=>({str:t=>z(e,t),strOr:(t,n)=>z(e,t)??n,bool:t=>L(z(e,t)),json:t=>F(z(e,t))}),H=()=>{let e={},t={str:(n,r)=>(r!==void 0&&(e[n]=r),t),bool:(n,r)=>(r!==void 0&&(e[n]=String(r)),t),json:(n,r)=>(r!=null&&(e[n]=JSON.stringify(r)),t),build:()=>e};return t},U=`0.2.0`,W=`ai-transport-js`,re=(e,t)=>{let n=e;return n.options.agents={...n.options.agents,...t},{params:{agent:Object.entries(t).map(([e,t])=>`${e}/${t}`).join(` `)}}},ie=(e,t)=>{let n=t?.adapterTag,r={[W]:U};return n&&(r[n]=U),re(e,r)},G=e=>{let t={[b]:e.role,[_]:e.codecMessageId};return e.runId!==void 0&&(t[m]=e.runId),e.runClientId!==void 0&&(t[v]=e.runClientId),e.parent&&(t[x]=e.parent),e.forkOf&&(t[S]=e.forkOf),e.regenerates&&(t[C]=e.regenerates),e.invocationId&&(t[h]=e.invocationId),e.inputClientId!==void 0&&(t[y]=e.inputClientId),e.inputCodecMessageId!==void 0&&(t[T]=e.inputCodecMessageId),e.inputEventId&&(t[g]=e.inputEventId),t},ae=e=>{let t={[m]:e.runId,[v]:e.runClientId};return e.reason!==void 0&&(t[w]=e.reason),e.parent!==void 0&&(t[x]=e.parent),e.forkOf!==void 0&&(t[S]=e.forkOf),e.regenerates!==void 0&&(t[C]=e.regenerates),e.invocationId!==void 0&&(t[h]=e.invocationId),e.inputClientId!==void 0&&(t[y]=e.inputClientId),e.inputCodecMessageId!==void 0&&(t[T]=e.inputCodecMessageId),t},K=e=>e===`ai-run-start`||e===`ai-run-suspend`||e===`ai-run-resume`||e===`ai-run-end`,oe=(e,t,n)=>{let r=t[m];if(!r)return;let i=t[`run-client-id`]??``;if(e===`ai-run-start`){let e=t[x],a=t[S],o=t[C];return{type:`start`,runId:r,clientId:i,serial:n,invocationId:t[`invocation-id`]??``,...e!==void 0&&{parent:e},...a!==void 0&&{forkOf:a},...o!==void 0&&{regenerates:o}}}if(e===`ai-run-suspend`)return{type:`suspend`,runId:r,clientId:i,serial:n,invocationId:t[`invocation-id`]??``};if(e===`ai-run-resume`)return{type:`resume`,runId:r,clientId:i,serial:n,invocationId:t[`invocation-id`]??``};if(e===`ai-run-end`){let e=t[`run-reason`]??`complete`;return{type:`end`,runId:r,clientId:i,serial:n,invocationId:t[`invocation-id`]??``,reason:e}}},se=(e,t,n)=>{if(e.has(t)||e.size<n)return;let r=e.keys().next().value;if(r!==void 0)return e.delete(r),r},ce=(e,t)=>{let n=[],r=new Set,i=t;for(;i!==void 0&&!r.has(i);)r.add(i),n.push(i),i=e.get(i)?.parentCodecMessageId;return n.toReversed()},le=(e,t,n)=>{let r=N(n),i=n.serial;if(K(n.name)){let t=oe(n.name,r,i);return t&&e.applyRunLifecycle(t),t}let{inputs:a,outputs:o}=t.decode(n);(a.length>0||o.length>0||r[`run-id`])&&e.applyMessage({inputs:a,outputs:o},r,i)},ue=(e,t,n,r,i)=>{let{inputs:a,outputs:o}=t.decode(r),s=n;for(let t of[...a,...o])s=e.fold(s,t,{serial:r.serial??``,messageId:i});return s},de=(e,t)=>{let n=new Set,r=[];for(let t of e)t.serial!==void 0&&!n.has(t.serial)&&(n.add(t.serial),r.push(t));if(t!==void 0)for(let e of t)e.serial!==void 0&&!n.has(e.serial)&&(n.add(e.serial),r.push(e));return r.toSorted(R)},fe=async(e,t,n)=>{let r=[],i=await e.history({limit:t});for(r.push(...i.items);i.hasNext()&&r.length<n;){let e=await i.next();if(!e)break;r.push(...e.items),i=e}return r},q=(e,t,n,r)=>{let i=e.createDecoder(),a=e.init(),o=0;for(let s of t){let t=N(s);if(t[`run-id`]!==n||K(s.name))continue;let c=t[_];if(r!==void 0&&c===r)break;a=ue(e,i,a,s,c??``),o++}return{projection:a,folded:o}},pe=(e,t,n)=>{let r=e.createDecoder(),i=e.init();for(let a of t){let t=N(a);t[`run-id`]===void 0&&t[`codec-message-id`]===n&&(i=ue(e,r,i,a,n))}return i},me=async e=>{let{channel:n,codec:r,runId:i,signal:a,logger:o,liveMessages:s}=e;if(a.aborted)throw new t.ErrorInfo(`unable to load run projection; run ${i} was cancelled`,j.InvalidArgument,400);await n.attach();let{projection:c,folded:l}=q(r,de(await fe(n,200,2e3),s),i);return o?.debug(`loadRunProjection(); folded run events`,{runId:i,folded:l}),c},he=async e=>{let{channel:n,codec:r,runId:i,signal:a,logger:o,liveMessages:s,assistantParentFallback:c,pageLimit:l,maxMessages:u}=e;if(a.aborted)throw new t.ErrorInfo(`unable to load conversation; run ${i} was cancelled`,j.InvalidArgument,400);let d=de(await fe(n,l,u),s),f=new Map,p=new Map;for(let e of d){if(K(e.name))continue;let t=N(e),n=t[_];if(n===void 0)continue;let r=t[m];r!==void 0&&p.set(r,n),f.has(n)||f.set(n,{runId:r,parentCodecMessageId:t[x]})}for(let e of d){if(e.name!==`ai-run-start`)continue;let t=N(e),n=t[m];if(n===void 0)continue;let r=p.get(n);if(r===void 0)continue;let i=f.get(r);i&&i.parentCodecMessageId===void 0&&(i.parentCodecMessageId=t[x])}let h=[],g=0;if(c!==void 0){let e=ce(f,c);g=e.length;for(let t of e){let e=f.get(t);if(e?.runId===i)continue;let n=e?.runId===void 0?pe(r,d,t):q(r,d,e.runId).projection;h.push(...r.getMessages(n).map(e=>e.message))}}let{projection:v,folded:y}=q(r,d,i);return h.push(...r.getMessages(v).map(e=>e.message)),o?.debug(`loadConversation(); built`,{runId:i,chainLength:g,totalMessages:h.length,folded:y}),{messages:h,projection:v}},ge=e=>{let t;return{promise:e===void 0?new Promise(()=>{}):e.aborted?Promise.resolve():new Promise(n=>{t=()=>{n()},e.addEventListener(`abort`,t,{once:!0})}),cleanup:()=>{t&&e&&e.removeEventListener(`abort`,t)}}},_e=async(e,t,n,r,i,a)=>{a?.trace(`pipeStream();`);let o=e.getReader(),s=ge(n),c=`complete`,l;try{for(;;){let e=await Promise.race([o.read(),s.promise.then(()=>`cancelled`)]);if(e===`cancelled`){c=`cancelled`,a?.debug(`pipeStream(); stream cancelled by AbortSignal`),r&&await r(async e=>t.publishOutput(e)),await t.cancel(`cancelled`);break}let{done:n,value:l}=e;if(n){await t.close(),a?.debug(`pipeStream(); stream completed`);break}await t.publishOutput(l,i?.(l))}}catch(e){c=`error`,l=e instanceof Error?e:Error(String(e)),a?.error(`pipeStream(); stream error`,{error:l.message});try{await t.close()}catch{}}finally{s.cleanup(),o.releaseLock()}return{reason:c,error:l}},ve=class{constructor(e,t){this._activeRuns=new Map,this._channel=e,this._logger=t?.withContext({component:`RunManager`})}async startRun(e,t,n,r){this._logger?.trace(`DefaultRunManager.startRun();`,{runId:e,clientId:t});let i=n??new AbortController,a=t??``;this._activeRuns.set(e,{controller:i,clientId:a});let o=r?.continuation===!0,s=ae({runId:e,runClientId:a,parent:o?void 0:r?.parent,forkOf:o?void 0:r?.forkOf,regenerates:o?void 0:r?.regenerates,invocationId:r?.invocationId,inputClientId:r?.inputClientId,inputCodecMessageId:r?.inputCodecMessageId});return await this._channel.publish({name:o?k:O,extras:{ai:{transport:s}}}),this._logger?.debug(`DefaultRunManager.startRun(); run started`,{runId:e}),i.signal}async suspendRun(e,t,n,r){this._logger?.trace(`DefaultRunManager.suspendRun();`,{runId:e}),await this._publishTerminal(te,e,{invocationId:t,inputClientId:n,inputCodecMessageId:r}),this._logger?.debug(`DefaultRunManager.suspendRun(); run suspended`,{runId:e})}async endRun(e,t,n,r,i){this._logger?.trace(`DefaultRunManager.endRun();`,{runId:e,reason:t}),await this._publishTerminal(A,e,{reason:t,invocationId:n,inputClientId:r,inputCodecMessageId:i}),this._logger?.debug(`DefaultRunManager.endRun(); run ended`,{runId:e,reason:t})}async _publishTerminal(e,t,n){let r=ae({runId:t,runClientId:this._activeRuns.get(t)?.clientId??``,...n});await this._channel.publish({name:e,extras:{ai:{transport:r}}}),this._activeRuns.delete(t)}getSignal(e){return this._activeRuns.get(e)?.controller.signal}getClientId(e){return this._activeRuns.get(e)?.clientId}cancel(e){this._logger?.debug(`DefaultRunManager.cancel();`,{runId:e}),this._activeRuns.get(e)?.controller.abort()}getActiveRunIds(){return[...this._activeRuns.keys()]}close(){this._logger?.trace(`DefaultRunManager.close();`,{activeRuns:this._activeRuns.size});for(let e of this._activeRuns.values())e.controller.abort();this._activeRuns.clear()}},ye=(e,t)=>new ve(e,t),be=async e=>{let{register:n,codec:r,invocationId:i,runId:a,expectedInputEventIds:o,timeoutMs:s,signal:c,logger:l}=e,u=new Set(o),d=u.size,f=[],p=[],m=new Set,h,_,v=e=>{let t=r.createDecoder(),n=N(e),i=n[`codec-message-id`]??``,{inputs:a,outputs:o}=t.decode(e),s=[...a,...o],c=r.init();for(let t of s)c=r.fold(c,t,{serial:e.serial??``,messageId:i});return r.getMessages(c).map(({message:t})=>({kind:`message`,message:t,codecMessageId:i,parentId:n[x],forkOf:n[S],headers:n,serial:e.serial}))};return new Promise((e,r)=>{let o=!1,y=new Set,b=()=>{},x,S=()=>{b(),x!==void 0&&clearTimeout(x),c.removeEventListener(`abort`,C)},C=()=>{o||(o=!0,S(),r(new t.ErrorInfo(`unable to look up input event; run ${a} was cancelled`,j.InvalidArgument,400)))};if(c.addEventListener(`abort`,C,{once:!0}),!o){if(b=n(n=>{if(o||n.serial!==void 0&&y.has(n.serial))return;n.serial!==void 0&&y.add(n.serial);let s=N(n),c=s[g];if(!c||!u.has(c)||m.has(c))return;m.add(c),h===void 0&&(h=s,_=n.clientId);let b;try{b=v(n)}catch(e){o=!0,S();let n=e instanceof t.ErrorInfo?e:void 0;r(new t.ErrorInfo(`unable to look up input event; decode failed for invocation ${i}: ${e instanceof Error?e.message:String(e)}`,j.InputEventNotFound,504,n));return}for(let e of b)f.push(e);p.push(n),!(m.size<d)&&(o=!0,S(),f.sort(R),l?.debug(`lookupInputEvents(); collected input events`,{runId:a,invocationId:i,count:f.length}),e({nodes:f,firstHeaders:h,firstClientId:_,rawMessages:p}))}),o){b();return}x=setTimeout(()=>{o||(o=!0,S(),r(new t.ErrorInfo(`unable to look up input event; received ${String(f.length)} of ${String(d)} input events for invocation ${i} within ${String(s)}ms`,j.InputEventNotFound,504)))},s)}})},xe=class{constructor(e){this._registeredRuns=new Map,this._runIdByInputCodecMessageId=new Map,this._deferredCancels=new Map,this._pendingInputEventLookups=new Map,this._inputEventBuffer=new Map,this._state=`ready`,this._codec=e.codec;let t={params:{...ie(e.client,e.codec).params,rewind:e.rewindWindow??`2m`}};this._channel=e.client.channels.get(e.channelName,t),this._logger=e.logger?.withContext({component:`AgentSession`}),this._onError=e.onError,this._runManager=ye(this._channel,this._logger),this._inputEventLookupTimeoutMs=e.inputEventLookupTimeoutMs??3e4,this._inputEventBufferLimit=e.inputEventBufferLimit??200,this._channelListener=e=>{this._handleChannelMessage(e)},this._hasAttachedOnce=this._channel.state===`attached`,this._onChannelStateChange=e=>{this._handleChannelStateChange(e)},this._channel.on(this._onChannelStateChange),this._logger?.debug(`DefaultAgentSession(); session created`)}connect(){return this._state===`closed`?Promise.reject(new t.ErrorInfo(`unable to connect; session is closed`,j.SessionClosed,400)):this._connectPromise?this._connectPromise:(this._logger?.trace(`DefaultAgentSession.connect();`),this._connectPromise=this._channel.subscribe(this._channelListener).then(()=>{this._logger?.debug(`DefaultAgentSession.connect(); subscribed and attached`)},e=>{let n=new t.ErrorInfo(`unable to subscribe to channel; ${e instanceof Error?e.message:String(e)}`,j.SessionSubscriptionError,500,e instanceof t.ErrorInfo?e:void 0);throw this._logger?.error(`DefaultAgentSession.connect(); subscribe failed`),this._onError?.(n),n}),this._connectPromise)}_registerInputEventListener(e,t){for(let n of e)this._pendingInputEventLookups.set(n,t);for(let n of e){let e=this._inputEventBuffer.get(n);if(e){this._inputEventBuffer.delete(n);for(let n of e)t(n)}}return()=>{for(let n of e)this._pendingInputEventLookups.get(n)===t&&this._pendingInputEventLookups.delete(n)}}createRun(e,t){return this._logger?.trace(`DefaultAgentSession.createRun();`,{inputEventId:e.inputEventId}),this._createRun(e,t??{})}async close(){if(this._state!==`closed`){this._state=`closed`,this._logger?.trace(`DefaultAgentSession.close();`),this._connectPromise&&this._channel.unsubscribe(this._channelListener),this._channel.off(this._onChannelStateChange);for(let e of this._registeredRuns.values())e.controller.abort();if(this._registeredRuns.clear(),this._runIdByInputCodecMessageId.clear(),this._deferredCancels.clear(),this._pendingInputEventLookups.clear(),this._inputEventBuffer.clear(),this._runManager.close(),this._connectPromise)try{await this._channel.detach()}catch(e){this._logger?.debug(`DefaultAgentSession.close(); channel detach failed`,{error:e})}this._logger?.debug(`DefaultAgentSession.close(); session closed`)}}async _handleCancelMessage(e){let t=N(e),n=t[m],r=t[T];if(!n&&!r){this._logger?.warn(`DefaultAgentSession._handleCancelMessage(); missing run-id and input-codec-message-id`,{serial:e.serial});return}let i=n??(r?this._runIdByInputCodecMessageId.get(r):void 0),a=i?this._registeredRuns.get(i):void 0;if(!a){r!==void 0&&this._bufferDeferredCancel(r,e);return}await this._cancelRegistration(a,e)}_bufferDeferredCancel(e,t){let n=se(this._deferredCancels,e,this._inputEventBufferLimit);n!==void 0&&this._logger?.warn(`DefaultAgentSession._bufferDeferredCancel(); deferred-cancel buffer full, dropping oldest`,{evictedInputCodecMessageId:n,limit:this._inputEventBufferLimit}),this._deferredCancels.set(e,t),this._logger?.debug(`DefaultAgentSession._bufferDeferredCancel(); buffered early cancel`,{inputCodecMessageId:e,serial:t.serial})}async _pullDeferredCancel(e,t){let n=this._deferredCancels.get(t);n!==void 0&&(this._deferredCancels.delete(t),this._logger?.debug(`DefaultAgentSession._pullDeferredCancel(); honouring buffered cancel`,{runId:e.runId,inputCodecMessageId:t}),await this._cancelRegistration(e,n))}async _cancelRegistration(e,n){let{runId:r}=e;this._logger?.debug(`DefaultAgentSession._cancelRegistration(); matched run`,{runId:r});let i={message:n,runId:r};try{if(e.onCancel&&!await e.onCancel(i)){this._logger?.debug(`DefaultAgentSession._cancelRegistration(); cancel rejected by onCancel`,{runId:r});return}e.controller.abort(),this._logger?.debug(`DefaultAgentSession._cancelRegistration(); run cancelled`,{runId:r})}catch(n){let i=new t.ErrorInfo(`unable to process cancel for run ${r}; onCancel handler threw: ${n instanceof Error?n.message:String(n)}`,j.CancelListenerError,500,n instanceof t.ErrorInfo?n:void 0);this._logger?.error(`DefaultAgentSession._cancelRegistration(); onCancel threw`,{runId:r}),(e.onError??this._onError)?.(i)}}_handleChannelStateChange(e){if(this._state===`closed`)return;let{current:n,resumed:r}=e;if(n===`attached`&&!this._hasAttachedOnce){this._hasAttachedOnce=!0;return}if(!(n===`failed`||n===`suspended`||n===`detached`||n===`attached`&&!r))return;this._logger?.error(`DefaultAgentSession._handleChannelStateChange(); channel continuity lost`,{current:n,resumed:r,previous:e.previous});let i=new t.ErrorInfo(`unable to deliver cancel messages; channel continuity lost (${n}${n===`attached`?`, resumed: false`:``})`,j.ChannelContinuityLost,500,e.reason);this._onError?.(i)}_handleChannelMessage(e){try{if(e.name===`ai-cancel`){this._handleCancelMessage(e).catch(e=>{let n=new t.ErrorInfo(`unable to route cancel message; ${e instanceof Error?e.message:String(e)}`,j.CancelListenerError,500,e instanceof t.ErrorInfo?e:void 0);this._logger?.error(`DefaultAgentSession._handleChannelMessage(); cancel routing error`),this._onError?.(n)});return}let n=N(e)[g];if(n!==void 0){let t=this._pendingInputEventLookups.get(n);if(t)t(e);else{let t=this._inputEventBuffer.get(n);if(t)t.push(e);else{let t=se(this._inputEventBuffer,n,this._inputEventBufferLimit);t!==void 0&&this._logger?.warn(`DefaultAgentSession._handleChannelMessage(); input-event buffer full, dropping oldest entry`,{evictedEventId:t,limit:this._inputEventBufferLimit}),this._inputEventBuffer.set(n,[e])}}}}catch(e){let n=new t.ErrorInfo(`unable to process channel message; ${e instanceof Error?e.message:String(e)}`,j.SessionSubscriptionError,500,e instanceof t.ErrorInfo?e:void 0);this._logger?.error(`DefaultAgentSession._handleChannelMessage(); subscription error`),this._onError?.(n)}}async _requireConnected(e){if(!this._connectPromise)throw new t.ErrorInfo(`unable to ${e}; connect() must be called before ${e}()`,j.InvalidArgument,400);return this._connectPromise}_createRun(e,n){let r=n.runId??crypto.randomUUID(),i=n.invocationId??crypto.randomUUID(),a=this._inputEventLookupTimeoutMs,{onMessage:o,onCancelled:s,onCancel:c,onError:l,signal:u}=n,d=new AbortController,f=`initialized`,p=u?AbortSignal.any([d.signal,u]):d.signal,h={runId:r,invocationId:i,controller:d,signal:p,onCancel:c,onError:l};this._registeredRuns.set(r,h);let g=this._logger,y=this._runManager,b=this._codec,w=this._channel,T=this._registeredRuns,E=this._runIdByInputCodecMessageId,ee=this._deferredCancels,D=this._requireConnected.bind(this),O=this._registerInputEventListener.bind(this),te=this._pullDeferredCancel.bind(this),k=e.inputEventId,A=[],ne={get messages(){return A}},M,N,P,F,I,L,R=!1,z,B,V,H=()=>{T.delete(r),L!==void 0&&(E.delete(L),ee.delete(L))},U,W;return{get runId(){return r},get invocationId(){return i},get abortSignal(){return p},get view(){return ne},get messages(){return W===void 0?U===void 0?A.map(e=>e.message):b.getMessages(U).map(e=>e.message):[...W]},start:async()=>{if(g?.trace(`Run.start();`,{runId:r,inputEventId:k}),await D(`start`),p.aborted)throw new t.ErrorInfo(`unable to start run; run ${r} was cancelled before start()`,j.InvalidArgument,400);if(f!==`initialized`)return;if(f=`started`,k&&a>0)try{let e=await be({register:e=>O([k],e),codec:b,invocationId:i,runId:r,expectedInputEventIds:[k],timeoutMs:a,signal:p,logger:g});for(let t of e.nodes)A.push(t);e.firstHeaders!==void 0&&(z=e.firstHeaders),e.firstClientId!==void 0&&(N=e.firstClientId),V=e.rawMessages}catch(e){let n=e instanceof t.ErrorInfo?e:new t.ErrorInfo(`unable to look up input event; ${e instanceof Error?e.message:String(e)}`,j.InputEventNotFound,504);throw H(),g?.error(`Run.start(); input-event lookup failed`,{runId:r,invocationId:i}),n}let e=z??A[0]?.headers;if(e){M=e[v],P=e[x],F=e[S],I=e[C],L=e[_];let t=e[m];R=t!==void 0,t!==void 0&&t!==r&&(T.delete(r),r=t,h.runId=r,T.set(r,h))}B=A.at(-1)?.codecMessageId??P,L!==void 0&&(E.set(L,r),await te(h,L));try{await y.startRun(r,M,d,{parent:B,forkOf:F,regenerates:I,invocationId:i,inputClientId:N,inputCodecMessageId:L,continuation:R})}catch(e){let n=new t.ErrorInfo(`unable to publish run-start for run ${r}; ${e instanceof Error?e.message:String(e)}`,j.RunLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw g?.error(`Run.start(); failed to publish run-start`,{runId:r}),n}g?.debug(`Run.start(); run started`,{runId:r,inputEventId:k})},addEvents:async e=>{if(g?.trace(`Run.addEvents();`,{runId:r,count:e.length}),await D(`addEvents`),f===`initialized`)throw new t.ErrorInfo(`unable to add events; start() must be called before addEvents() (run ${r})`,j.InvalidArgument,400);let n=y.getClientId(r);try{for(let t of e){let e=G({role:`assistant`,runId:r,codecMessageId:t.codecMessageId,runClientId:n,invocationId:i,inputClientId:N,inputCodecMessageId:L}),a=b.createEncoder(w,{extras:{headers:e},onMessage:o});for(let e of t.events)await a.publishOutput(e);await a.close()}}catch(e){let n=new t.ErrorInfo(`unable to publish events for run ${r}; ${e instanceof Error?e.message:String(e)}`,j.RunLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw g?.error(`Run.addEvents(); publish failed`,{runId:r}),n}g?.debug(`Run.addEvents(); events published`,{runId:r,count:e.length})},loadProjection:async()=>{g?.trace(`Run.loadProjection();`,{runId:r}),await D(`loadProjection`);let e=await me({channel:w,codec:b,runId:r,signal:p,logger:g,liveMessages:V});return U=e,e},loadConversation:async e=>{g?.trace(`Run.loadConversation();`,{runId:r}),await D(`loadConversation`);let{messages:t,projection:n}=await he({channel:w,codec:b,runId:r,signal:p,logger:g,liveMessages:V,assistantParentFallback:B,pageLimit:e?.pageLimit??200,maxMessages:e?.maxMessages??2e3});return U=n,W=t,t},pipe:async(e,n)=>{if(g?.trace(`Run.pipe();`,{runId:r}),await D(`pipe`),f===`initialized`)throw new t.ErrorInfo(`unable to pipe stream; start() must be called before pipe() (run ${r})`,j.InvalidArgument,400);let a=y.getClientId(r),c=n?.parent??B,u=n?.forkOf??F,d=I,m=crypto.randomUUID(),h=G({role:`assistant`,runId:r,codecMessageId:m,runClientId:a,parent:c,forkOf:u,invocationId:i,inputClientId:N,inputCodecMessageId:L,regenerates:d}),_=await _e(e,b.createEncoder(w,{extras:{headers:h},onMessage:o,messageId:m}),p,s,n?.resolveWriteOptions,g);if(_.error){let e=new t.ErrorInfo(`unable to pipe response for run ${r}; ${_.error.message}`,j.StreamError,500,_.error instanceof t.ErrorInfo?_.error:void 0);g?.error(`Run.pipe(); stream error`,{runId:r}),l?.(e)}return g?.debug(`Run.pipe(); stream finished`,{runId:r,reason:_.reason}),_},suspend:async()=>{if(g?.trace(`Run.suspend();`,{runId:r}),await D(`suspend`),f===`initialized`)throw new t.ErrorInfo(`unable to suspend run; start() must be called before suspend() (run ${r})`,j.InvalidArgument,400);if(f!==`ended`){f=`ended`;try{await y.suspendRun(r,i,N,L)}catch(e){let n=new t.ErrorInfo(`unable to publish run-suspend for run ${r}; ${e instanceof Error?e.message:String(e)}`,j.RunLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw g?.error(`Run.suspend(); failed to publish run-suspend`,{runId:r}),n}finally{H()}g?.debug(`Run.suspend(); run suspended`,{runId:r})}},end:async e=>{if(g?.trace(`Run.end();`,{runId:r,reason:e}),await D(`end`),f===`initialized`)throw new t.ErrorInfo(`unable to end run; start() must be called before end() (run ${r})`,j.InvalidArgument,400);if(f!==`ended`){f=`ended`;try{await y.endRun(r,e,i,N,L)}catch(e){let n=new t.ErrorInfo(`unable to publish run-end for run ${r}; ${e instanceof Error?e.message:String(e)}`,j.RunLifecycleError,500,e instanceof t.ErrorInfo?e:void 0);throw g?.error(`Run.end(); failed to publish run-end`,{runId:r}),n}finally{H()}g?.debug(`Run.end(); run ended`,{runId:r,reason:e})}}}}},Se=e=>new xe(e),Ce=e=>({logAction:(t,n,r)=>{e.error(n,{detail:r})},shouldLog:()=>!0}),we=t.Realtime.EventEmitter,J=class extends we{constructor(e){super(Ce(e))}},Te=function(e){return e.Trace=`trace`,e.Debug=`debug`,e.Info=`info`,e.Warn=`warn`,e.Error=`error`,e.Silent=`silent`,e}({}),Ee=(e,t,n)=>{let r=n?`, context: ${JSON.stringify(n)}`:``,i=`[${new Date().toISOString()}] ${t.valueOf().toUpperCase()} ably-ai-transport: ${e}${r}`;switch(t){case`trace`:case`debug`:console.log(i);break;case`info`:console.info(i);break;case`warn`:console.warn(i);break;case`error`:console.error(i);break;case`silent`:break}},De=e=>new ke(e.logHandler??Ee,e.logLevel),Oe=new Map([[`trace`,0],[`debug`,1],[`info`,2],[`warn`,3],[`error`,4],[`silent`,5]]),ke=class e{constructor(e,n,r){this._handler=e,this._context=r;let i=Oe.get(n);if(i===void 0)throw new t.ErrorInfo(`unable to create logger; invalid log level: ${n}`,j.InvalidArgument,400);this._levelNumber=i}trace(e,t){this._write(e,`trace`,0,t)}debug(e,t){this._write(e,`debug`,1,t)}info(e,t){this._write(e,`info`,2,t)}warn(e,t){this._write(e,`warn`,3,t)}error(e,t){this._write(e,`error`,4,t)}withContext(t){let n=[...Oe.entries()].find(([,e])=>e===this._levelNumber)?.[0]??`error`;return new e(this._handler,n,this._mergeContext(t))}_write(e,t,n,r){n>=this._levelNumber&&this._handler(e,t,this._mergeContext(r))}_mergeContext(e){return this._context?e?{...this._context,...e}:this._context:e??void 0}},Y=e=>e.kind===`run`?e.runId:e.codecMessageId,X=e=>e.kind===`run`?e.startSerial:e.serial,Ae=(e,t,n)=>{let r=e.get(t);r||(r=new Set,e.set(t,r)),r.add(n)},je=(e,t,n)=>{let r=e.get(t);r&&(r.delete(n),r.size===0&&e.delete(t))},Me=class{constructor(e,t){this._nodeIndex=new Map,this._codecMessageIdToNodeKey=new Map,this._sortedNodes=[],this._parentIndex=new Map,this._replyRunsByInput=new Map,this._seqCounter=0,this._structuralVersion=0,this._siblingCache=new Map,this._siblingCacheVersion=-1,this._codec=e,this._logger=t,this._emitter=new J(t)}_compareNodes(e,t){let n=X(e.node),r=X(t.node);return n===void 0&&r===void 0?e.insertSeq-t.insertSeq:n===void 0?1:r===void 0||n<r?-1:n>r?1:e.insertSeq-t.insertSeq}_insertSortedNode(e){if(X(e.node)===void 0){this._sortedNodes.push(e);return}let t=0,n=this._sortedNodes.length;for(;t<n;){let r=t+n>>>1,i=this._sortedNodes[r];if(!i)break;this._compareNodes(i,e)<=0?t=r+1:n=r}this._sortedNodes.splice(t,0,e)}_removeSortedNode(e){let t=this._sortedNodes.indexOf(e);t!==-1&&this._sortedNodes.splice(t,1)}_insertNode(e,t,n){this._nodeIndex.set(e,t),this._addToParentIndex(n,e),this._insertSortedNode(t),this._structuralVersion++}_promoteSerial(e){this._removeSortedNode(e),this._insertSortedNode(e),this._structuralVersion++}_foldInto(e,t,n,r){for(let i of t)try{e.node.projection=this._codec.fold(e.node.projection,i,{serial:n??``,messageId:r})}catch(t){this._logger.error(`Tree._foldInto(); fold threw`,{key:Y(e.node),messageId:r,err:t})}}_addToParentIndex(e,t){Ae(this._parentIndex,e,t)}_removeFromParentIndex(e,t){je(this._parentIndex,e,t)}_parentKeyOf(e){let t=e.parentCodecMessageId;return t===void 0?void 0:this._codecMessageIdToNodeKey.get(t)}_inputGroupRoot(e){let t=e,n=new Set([Y(t)]);for(;t.forkOf!==void 0&&!n.has(t.forkOf);){let e=this._nodeIndex.get(t.forkOf);if(e?.node.kind!==`input`||e.node.parentCodecMessageId!==t.parentCodecMessageId)break;t=e.node,n.add(Y(t))}return t}_getSiblingGroup(e){this._siblingCacheVersion!==this._structuralVersion&&(this._siblingCache.clear(),this._siblingCacheVersion=this._structuralVersion);let t=this._siblingCache.get(e);if(t)return t;let n=this._nodeIndex.get(e);if(!n)return[];let r=n.node;r.kind===`input`&&(r=this._inputGroupRoot(r));let i=r.parentCodecMessageId,a=[],o=this._parentIndex.get(i);if(o)for(let e of o){let t=this._nodeIndex.get(e);t&&this._isSiblingOf(t.node,r)&&a.push(t)}a.sort((e,t)=>this._compareNodes(e,t));for(let e of a)this._siblingCache.set(Y(e.node),a);return this._siblingCache.set(e,a),a}_isSiblingOf(e,t){if(e.kind!==t.kind||e.parentCodecMessageId!==t.parentCodecMessageId)return!1;if(e.kind===`run`)return!0;let n=Y(t);if(Y(e)===n)return!0;let r=e,i=new Set([Y(r)]);for(;r.kind===`input`&&r.forkOf!==void 0;){if(r.forkOf===n)return!0;if(i.has(r.forkOf))break;let e=this._nodeIndex.get(r.forkOf);if(!e)break;r=e.node,i.add(Y(r))}return!1}getGroupRoot(e){let t=this._nodeIndex.get(e);if(!t)return e;if(t.node.kind===`input`)return Y(this._inputGroupRoot(t.node));let n=this._getSiblingGroup(e)[0]?.node;return n?Y(n):e}visibleNodes(e=new Map){this._logger.trace(`DefaultTree.visibleNodes();`);let t=[],n=new Set,r=new Map;for(let i of this._sortedNodes){let a=i.node,o=Y(a),s=this._parentKeyOf(a);if(s!==void 0&&!n.has(s))continue;let c=this._getSiblingGroup(o);if(c.length>1){let t=this.getGroupRoot(o),n=r.get(t);if(n===void 0){let i=e.get(t);if(i!==void 0&&c.some(e=>Y(e.node)===i))n=i;else{let e=c.at(-1);if(!e)break;n=Y(e.node)}r.set(t,n)}if(o!==n)continue}n.add(o),t.push(a)}return t}getRunNode(e){this._logger.trace(`DefaultTree.getRunNode();`,{runId:e});let t=this._nodeIndex.get(e)?.node;return t?.kind===`run`?t:void 0}getNode(e){return this._logger.trace(`DefaultTree.getNode();`,{key:e}),this._nodeIndex.get(e)?.node}getNodeByCodecMessageId(e){this._logger.trace(`DefaultTree.getNodeByCodecMessageId();`,{codecMessageId:e});let t=this._codecMessageIdToNodeKey.get(e);return t===void 0?void 0:this._nodeIndex.get(t)?.node}getReplyRuns(e){let t=this._replyRunsByInput.get(e);if(!t)return[];let n=[];for(let e of t){let t=this._nodeIndex.get(e)?.node;t?.kind===`run`&&n.push(t)}return n}getSiblingNodes(e){return this._logger.trace(`DefaultTree.getSiblingNodes();`,{key:e}),this._getSiblingGroup(e).map(e=>e.node)}applyMessage(e,t,n){let r=t[m],i=t[_],a=r===void 0&&i!==void 0&&t.role===`user`&&e.inputs.length>0?i:void 0;if(r===void 0&&a===void 0){this._logger.warn(`Tree.applyMessage(); message has no run-id and is not a user input; skipping`);return}let o=[...e.inputs,...e.outputs],s=a??r;if(o.length===0&&s!==void 0&&!this._nodeIndex.has(s))return;let c=this._structuralVersion;a===void 0?r!==void 0&&this._applyRunMessage(r,e,t,n):this._applyInputMessage(a,t,n,o),this._structuralVersion!==c&&this._emitter.emit(`update`)}_applyInputMessage(e,t,n,r){let i=this._nodeIndex.get(e);i?i.node.kind===`input`&&n&&!i.node.serial&&(this._logger.debug(`Tree.applyMessage(); promoting input serial`,{codecMessageId:e,serial:n}),i.node.serial=n,this._promoteSerial(i)):(i=this._createInputNodeFromHeaders(e,t,n),this._insertNode(e,i,i.node.parentCodecMessageId),this._codecMessageIdToNodeKey.set(e,e),this._logger.debug(`Tree.applyMessage(); created input node`,{codecMessageId:e})),this._foldInto(i,r,n,e),this._emitter.emit(`output`,{runId:void 0,inputCodecMessageId:e,codecMessageId:e,serial:n,events:[]})}_applyRunMessage(e,t,n,r){let i=n[_],a=n[T],o=[...t.inputs,...t.outputs],s=t.outputs,c=this._nodeIndex.get(e);if(!c&&i!==void 0){let e=this._codecMessageIdToNodeKey.get(i),t=e===void 0?void 0:this._nodeIndex.get(e);t?.node.kind===`run`&&t.node.startSerial===void 0&&(c=t)}c?r&&c.node.kind===`run`&&!c.node.startSerial&&(this._logger.debug(`Tree.applyMessage(); promoting startSerial`,{runId:e,serial:r}),c.node.startSerial=r,this._promoteSerial(c)):(c=this._createRunFromHeaders(e,n,r),this._insertNode(e,c,c.node.parentCodecMessageId),this._indexReplyRun(c.node,e),this._logger.debug(`Tree.applyMessage(); created new Run`,{runId:e}));let l=Y(c.node);i&&this._codecMessageIdToNodeKey.set(i,l),this._foldInto(c,o,r,i),this._emitter.emit(`output`,{runId:l,inputCodecMessageId:a,codecMessageId:i,serial:r,events:s})}_indexReplyRun(e,t){e.parentCodecMessageId!==void 0&&Ae(this._replyRunsByInput,e.parentCodecMessageId,t)}applyRunLifecycle(e){this._logger.trace(`DefaultTree.applyRunLifecycle();`,{type:e.type,runId:e.runId});let t=this._structuralVersion;switch(e.type){case`start`:this._applyRunStart(e);break;case`suspend`:this._applyRunSuspend(e);break;case`resume`:this._applyRunResume(e);break;case`end`:this._applyRunEnd(e);break}this._emitter.emit(`run`,e),this._structuralVersion!==t&&this._emitter.emit(`update`)}_applyRunStart(e){let t=this._nodeIndex.get(e.runId);if(t?.node.kind===`run`){let n=t.node;if(n.status!==`active`&&(n.status=`active`),e.serial&&!n.startSerial&&(n.startSerial=e.serial,this._promoteSerial(t)),n.parentCodecMessageId===void 0&&e.parent!==void 0&&(n.parentCodecMessageId=e.parent,this._removeFromParentIndex(void 0,e.runId),this._addToParentIndex(n.parentCodecMessageId,e.runId),this._indexReplyRun(n,e.runId),this._structuralVersion++),n.forkOf===void 0&&e.forkOf!==void 0){let t=this._codecMessageIdToNodeKey.get(e.forkOf);t!==void 0&&t!==e.runId&&(n.forkOf=t,this._structuralVersion++)}n.regeneratesCodecMessageId===void 0&&e.regenerates!==void 0&&(n.regeneratesCodecMessageId=e.regenerates,this._structuralVersion++),n.invocationId===``&&e.invocationId!==``&&(n.invocationId=e.invocationId)}else if(!t){let t=this._createRunFromLifecycle(e);this._insertNode(e.runId,t,t.node.parentCodecMessageId),this._indexReplyRun(t.node,e.runId)}}_applyRunSuspend(e){let t=this._nodeIndex.get(e.runId);t?.node.kind===`run`&&(t.node.status=`suspended`,t.node.endSerial=e.serial)}_applyRunResume(e){let t=this._nodeIndex.get(e.runId);t?.node.kind===`run`&&t.node.status===`suspended`&&(t.node.status=`active`)}_applyRunEnd(e){let t=this._nodeIndex.get(e.runId);t?.node.kind===`run`&&(t.node.status=e.reason,t.node.endSerial=e.serial)}delete(e){let t=this._nodeIndex.get(e);t&&(this._logger.debug(`Tree.delete();`,{key:e}),this._removeFromParentIndex(t.node.parentCodecMessageId,e),this._removeSortedNode(t),this._nodeIndex.delete(e),t.node.kind===`run`&&t.node.parentCodecMessageId!==void 0&&je(this._replyRunsByInput,t.node.parentCodecMessageId,e),this._structuralVersion++,this._emitter.emit(`update`))}_createRunFromHeaders(e,t,n){let r=t[S];return this._buildRunNode({runId:e,parentCodecMessageId:t[x],forkOf:r?this._codecMessageIdToNodeKey.get(r):void 0,regeneratesCodecMessageId:t[C],clientId:t[`run-client-id`]??``,invocationId:t[`invocation-id`]??``,startSerial:n})}_buildRunNode(e){return{node:{kind:`run`,runId:e.runId,parentCodecMessageId:e.parentCodecMessageId,forkOf:e.forkOf,regeneratesCodecMessageId:e.regeneratesCodecMessageId,clientId:e.clientId,invocationId:e.invocationId,status:`active`,projection:this._codec.init(),startSerial:e.startSerial,endSerial:void 0},insertSeq:this._seqCounter++}}_createInputNodeFromHeaders(e,t,n){let r=t[S];return{node:{kind:`input`,codecMessageId:e,parentCodecMessageId:t[x],forkOf:r,projection:this._codec.init(),serial:n},insertSeq:this._seqCounter++}}_createRunFromLifecycle(e){let t=e.forkOf;return this._buildRunNode({runId:e.runId,parentCodecMessageId:e.parent,forkOf:t?this._codecMessageIdToNodeKey.get(t):void 0,regeneratesCodecMessageId:e.regenerates,clientId:e.clientId,invocationId:e.invocationId,startSerial:e.serial})}on(e,t){let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}emitAblyMessage(e){this._logger.trace(`DefaultTree.emitAblyMessage();`),this._emitter.emit(`ably-message`,e)}},Ne=(e,t)=>new Me(e,t),Pe=(e,t)=>{for(let n of t){let t=N(n),r=t[_];if(!r)continue;let i=n.action,a=i===`message.create`&&`discrete`in t,o=t.stream===`true`&&(i===`message.create`||i===`message.update`||i===`message.append`),s=t[d],c=s===`complete`||s===`cancelled`;(a||o)&&e.startedCodecMessageIds.add(r),(a||c)&&e.terminatedCodecMessageIds.add(r),e.startedCodecMessageIds.has(r)&&e.terminatedCodecMessageIds.has(r)&&e.completedCodecMessageIds.add(r)}},Z=async(e,t,n)=>{e.rawMessages.push(...t.items),e.lastAblyPage=t,Pe(e,t.items);let r=e.returnedCount+n;for(;e.completedCodecMessageIds.size<r&&t.hasNext();){e.logger.debug(`loadHistory.fetchUntilLimit(); fetching next page`,{collected:e.rawMessages.length,completed:e.completedCodecMessageIds.size});let n=await t.next();if(!n)break;t=n,e.rawMessages.push(...n.items),e.lastAblyPage=n,Pe(e,n.items)}},Q=(e,t)=>{let n=e.completedCodecMessageIds.size,r=Math.min(t,Math.max(0,n-e.returnedCount));e.returnedCount+=r;let i=n>e.returnedCount,a=e.lastAblyPage?.hasNext()??!1,o=e.rawMessages.length-e.returnedRawCount>0?e.rawMessages.slice(e.returnedRawCount).toReversed():[];return e.returnedRawCount=e.rawMessages.length,{rawMessages:o,hasNext:()=>i||a,next:async()=>{if(i)return Q(e,t);if(!a||!e.lastAblyPage)return;let n=await e.lastAblyPage.next();if(n)return await Z(e,n,t),Q(e,t)}}},Fe=async(e,t,n)=>{let r=t?.limit??100,i={rawMessages:[],returnedCount:0,returnedRawCount:0,lastAblyPage:void 0,startedCodecMessageIds:new Set,terminatedCodecMessageIds:new Set,completedCodecMessageIds:new Set,logger:n};n.trace(`loadHistory();`,{limit:r});let a=r*10;return await e.attach(),await Z(i,await e.history({untilAttach:!0,limit:a}),r),Q(i,r)},Ie=e=>Array.isArray(e)?e:[e],Le=3,$=e=>({runId:e.runId,clientId:e.clientId,status:e.status,invocationId:e.invocationId}),Re=class{constructor(e){this._branchSelections=new Map,this._regenSelections=new Map,this._withheldRunIds=new Set,this._lastVisibleNodeKeys=[],this._lastVisibleProjections=[],this._lastVisibleMessagePairs=[],this._lastVisibleNodeKeySet=new Set,this._hasMoreHistory=!1,this._withheldBuffer=[],this._unsubs=[],this._cachedNodes=[],this._loadingOlder=!1,this._processingHistory=!1,this._closed=!1,this._tree=e.tree,this._channel=e.channel,this._codec=e.codec,this._sendDelegate=e.sendDelegate,this._onClose=e.onClose,this._logger=e.logger.withContext({component:`View`}),this._logger.trace(`DefaultView();`),this._emitter=new J(this._logger),this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._unsubs.push(this._tree.on(`update`,()=>{this._onTreeUpdate()}),this._tree.on(`ably-message`,e=>{this._onTreeAblyMessage(e)}),this._tree.on(`run`,e=>{this._onTreeRun(e)}),this._tree.on(`output`,e=>{this._onTreeOutput(e)}))}_onTreeOutput(e){this._processingHistory||(e.runId!==void 0&&this._lastVisibleNodeKeySet.has(e.runId)||e.inputCodecMessageId!==void 0&&this._lastVisibleNodeKeySet.has(e.inputCodecMessageId))&&(this._lastVisibleProjections=this._cachedNodes.map(e=>e.projection),this._lastVisibleMessagePairs=this._extractMessages(this._cachedNodes),this._emitter.emit(`update`))}getMessages(){return this._lastVisibleMessagePairs}runs(){return this._cachedNodes.filter(e=>e.kind===`run`).map(e=>$(e))}_computeFlatNodes(){let e=this._treeVisibleNodes();return this._withheldRunIds.size===0?e:e.filter(e=>!this._withheldRunIds.has(Y(e)))}_recomputeAndEmit(){this._cachedNodes=this._computeFlatNodes(),this._updateVisibleSnapshot(this._cachedNodes),this._emitter.emit(`update`)}_recomputeAndEmitIfChanged(){let e=this._computeFlatNodes();this._visibleChanged(e)&&(this._cachedNodes=e,this._updateVisibleSnapshot(e),this._emitter.emit(`update`))}_runByCodecMessageId(e){let t=this._tree.getNodeByCodecMessageId(e);return t?.kind===`run`?t:void 0}_extractMessages(e){let t=[];for(let n of e)for(let e of this._codec.getMessages(n.projection))t.push(e);return t}hasOlder(){return this._withheldBuffer.length>0||this._hasMoreHistory}async loadOlder(e=100){if(!(this._closed||this._loadingOlder)){this._loadingOlder=!0,this._logger.trace(`DefaultView.loadOlder();`,{limit:e});try{if(this._withheldBuffer.length>0){let t=this._withheldBuffer.splice(-e,e);this._releaseWithheld(t);return}if(!this._hasMoreHistory&&!this._lastHistoryPage){await this._loadFirstPage(e);return}if(!this._hasMoreHistory)return;if(!this._lastHistoryPage?.hasNext()){this._hasMoreHistory=!1;return}let t=await this._lastHistoryPage.next();if(this._closed||!t){t||(this._hasMoreHistory=!1);return}await this._revealFromPage(t,e)}catch(e){throw this._logger.error(`DefaultView.loadOlder(); failed`,{error:e}),e}finally{this._loadingOlder=!1}}}runOf(e){this._logger.trace(`DefaultView.runOf();`,{codecMessageId:e});let t=this._tree.getNodeByCodecMessageId(e);if(!t)return;if(t.kind===`run`)return $(t);let n=this._selectedReplyRun(t.codecMessageId);return n?$(n):void 0}_selectedReplyRun(e){let t=this._tree.getReplyRuns(e);if(t.length===0)return;if(t.length===1)return t[0];let n=this._tree.getGroupRoot(t[0]?.runId??``),r=this._regenSelections.get(n),i=r&&r.kind!==`pending`?r.selectedRunId:void 0;if(i!==void 0){let e=t.find(e=>e.runId===i);if(e)return e}return t.toSorted((e,t)=>(e.startSerial??`￿`).localeCompare(t.startSerial??`￿`)).at(-1)}run(e){this._logger.trace(`DefaultView.run();`,{runId:e});let t=this._tree.getRunNode(e);return t?$(t):void 0}branchSelection(e){let t=this._resolveMessageBranchPoint(e);if(t){let e=t.siblings.flatMap(e=>{let t=this._codec.getMessages(e.projection).at(0);return t?[t.message]:[]});if(e.length>0){let n=this._resolveSelectedIndex(t),r=Math.max(0,Math.min(n,e.length-1)),i=e[r];return{hasSiblings:e.length>1,siblings:e,index:r,selected:i}}}let n=this._tree.getNodeByCodecMessageId(e);if(n){let t=this._codec.getMessages(n.projection).find(t=>t.codecMessageId===e);if(t!==void 0)return{hasSiblings:!1,siblings:[t.message],index:0,selected:t.message}}return{hasSiblings:!1,siblings:[],index:0,selected:void 0}}selectSibling(e,t){this._logger.trace(`DefaultView.selectSibling();`,{codecMessageId:e,index:t});let n=this._resolveMessageBranchPoint(e);if(!n)return;let r=Math.max(0,Math.min(t,n.siblings.length-1)),i=n.siblings[r];i&&(n.kind===`fork-of`?(this._branchSelections.set(n.groupRoot,{kind:`user`,selectedKey:Y(i)}),this._logger.debug(`DefaultView.selectSibling(); fork-of`,{codecMessageId:e,index:r,selectedKey:Y(i)})):(this._regenSelections.set(n.groupRoot,{kind:`user`,selectedRunId:Y(i)}),this._logger.debug(`DefaultView.selectSibling(); regenerate`,{codecMessageId:e,index:r,selectedRunId:Y(i),groupRoot:n.groupRoot})),this._recomputeAndEmit())}_resolveSelectedIndex(e){if(e.kind===`fork-of`){let t=this._branchSelections.get(e.groupRoot);if(!t)return e.siblings.length-1;let n=e.siblings.findIndex(e=>Y(e)===t.selectedKey);return n===-1?e.siblings.length-1:n}let t=this._regenSelections.get(e.groupRoot);if(!t||t.kind===`pending`)return e.siblings.length-1;let n=e.siblings.findIndex(e=>Y(e)===t.selectedRunId);return n===-1?e.siblings.length-1:n}_resolveMessageBranchPoint(e){let t=this._tree.getNodeByCodecMessageId(e);if(!t)return;if(t.kind===`input`){let e=this._tree.getSiblingNodes(t.codecMessageId);return e.length>1?{kind:`fork-of`,groupRoot:this._tree.getGroupRoot(t.codecMessageId),siblings:e}:void 0}let n=this._tree.getSiblingNodes(t.runId);if(n.length>1&&this._codec.getMessages(t.projection).at(0)?.codecMessageId===e)return{kind:`regen`,groupRoot:this._tree.getGroupRoot(t.runId),siblings:n}}async send(e,n){if(this._logger.trace(`DefaultView.send();`),this._closed)throw new t.ErrorInfo(`unable to send; view is closed`,j.InvalidArgument,400);let r=Ie(e),i=this._lastVisibleMessagePairs.at(-1)?.codecMessageId,a=await this._sendDelegate(r,n,i);return this._applyForkAutoSelect(a,n),a}_applyForkAutoSelect(e,t){if(!t?.forkOf)return;let n=e.optimisticCodecMessageIds.at(0);if(n===void 0)return;let r=this._tree.getGroupRoot(n);this._branchSelections.set(r,{kind:`auto`,selectedKey:n}),this._recomputeAndEmit()}_applyRegenerateAutoSelect(e,t){let n=this._runByCodecMessageId(t);if(!n)return;let r=this._tree.getGroupRoot(n.runId);this._regenSelections.set(r,{kind:`pending`,carrierCodecMessageId:e.inputCodecMessageId}),this._logger.debug(`DefaultView._applyRegenerateAutoSelect(); deferring regenerate selection`,{anchorCodecMessageId:t,groupRoot:r,carrier:e.inputCodecMessageId}),this._resolvePendingRegenSelections(),this._recomputeAndEmitIfChanged()}async regenerate(e,n){if(this._logger.trace(`DefaultView.regenerate();`,{messageId:e}),this._closed)throw new t.ErrorInfo(`unable to regenerate; view is closed`,j.InvalidArgument,400);let r=this._runByCodecMessageId(e);if(!r)throw new t.ErrorInfo(`unable to regenerate; message not found in tree: ${e}`,j.InvalidArgument,400);let i=this._findParentMsgId(r,e);if(!i)throw new t.ErrorInfo(`unable to regenerate; parent user message not found for ${e}`,j.InvalidArgument,400);let a=e;r.regeneratesCodecMessageId!==void 0&&this._codec.getMessages(r.projection).at(0)?.codecMessageId===e&&(a=r.regeneratesCodecMessageId);let o={...n,parent:i},s=this._codec.createRegenerate(a,i),c=await this._sendDelegate([s],o,i);return this._applyRegenerateAutoSelect(c,a),c}async edit(e,n,r){if(this._logger.trace(`DefaultView.edit();`,{messageId:e}),this._closed)throw new t.ErrorInfo(`unable to edit; view is closed`,j.InvalidArgument,400);let i=this._tree.getNodeByCodecMessageId(e);if(!i)throw new t.ErrorInfo(`unable to edit; message not found in tree: ${e}`,j.InvalidArgument,400);let a=this._findParentMsgId(i,e);return this.send(n,{...r,forkOf:e,parent:a})}_findParentMsgId(e,t){let n=this._lastVisibleMessagePairs,r=n.findIndex(e=>e.codecMessageId===t);if(r>0)return n[r-1]?.codecMessageId;if(r===0)return;let i=this._codec.getMessages(e.projection),a=i.findIndex(e=>e.codecMessageId===t);if(a>0)return i[a-1]?.codecMessageId;if(a===0&&e.parentCodecMessageId!==void 0){let t=this._tree.getNodeByCodecMessageId(e.parentCodecMessageId);if(t)return this._codec.getMessages(t.projection).at(-1)?.codecMessageId}}on(e,t){let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}close(){if(!this._closed){this._logger.info(`DefaultView.close();`),this._closed=!0,this._loadingOlder=!1;for(let e of this._unsubs)e();this._unsubs.length=0,this._emitter.off(),this._branchSelections.clear(),this._regenSelections.clear(),this._withheldRunIds.clear(),this._withheldBuffer.length=0,this._onClose?.()}}async _loadFirstPage(e){let t=e*Le,n=await Fe(this._channel,{limit:t},this._logger);this._closed||await this._revealFromPage(n,e)}async _revealFromPage(e,t){let n=new Set(this._treeVisibleNodes().map(e=>Y(e))),{newVisible:r,lastPage:i}=await this._loadUntilVisible(e,t,n);this._closed||(this._lastHistoryPage=i,this._hasMoreHistory=i.hasNext(),this._splitReveal(r,t))}_splitReveal(e,t){let n=0,r=e.length;for(let i=e.length-1;i>=0;i--){if(e[i]?.kind===`run`){if(n===t)break;n++}r=i}let i=e.slice(r),a=e.slice(0,r);for(let e of a)this._withheldRunIds.add(Y(e));this._withheldBuffer.push(...a),this._releaseWithheld(i)}_processHistoryPage(e){this._processingHistory=!0;try{let t=this._codec.createDecoder();for(let n of e.rawMessages)le(this._tree,t,n);for(let t of e.rawMessages)this._tree.emitAblyMessage(t)}finally{this._processingHistory=!1}}async _loadUntilVisible(e,t,n){this._processHistoryPage(e);let r=e,i=()=>{let e=0;for(let t of this._treeVisibleNodes())t.kind===`run`&&!n.has(Y(t))&&e++;return e};for(;i()<t&&r.hasNext();){let e=await r.next();if(!e||this._closed)break;this._processHistoryPage(e),r=e}return{newVisible:this._treeVisibleNodes().filter(e=>!n.has(Y(e))),lastPage:r}}_releaseWithheld(e){for(let t of e)this._withheldRunIds.delete(Y(t));e.length>0&&this._recomputeAndEmit()}_updateVisibleSnapshot(e){let t=e??this._cachedNodes;this._lastVisibleNodeKeys=t.map(e=>Y(e)),this._lastVisibleNodeKeySet=new Set(this._lastVisibleNodeKeys),this._lastVisibleProjections=t.map(e=>e.projection),this._lastVisibleMessagePairs=this._extractMessages(t)}_onTreeUpdate(){this._processingHistory||(this._pinBranchSelections(),this._resolvePendingRegenSelections(),this._recomputeAndEmitIfChanged())}_resolveSelections(){let e=new Map;for(let[t,n]of this._branchSelections)e.set(t,n.selectedKey);for(let[t,n]of this._regenSelections)n.kind!==`pending`&&e.set(t,n.selectedRunId);return e}_treeVisibleNodes(){return this._tree.visibleNodes(this._resolveSelections())}_pinBranchSelections(){for(let e of this._lastVisibleNodeKeys){if(this._tree.getNode(e)?.kind!==`input`||this._tree.getSiblingNodes(e).length<=1)continue;let t=this._tree.getGroupRoot(e);this._branchSelections.get(t)||this._branchSelections.set(t,{kind:`pinned`,selectedKey:e})}}_resolvePendingRegenSelections(){for(let[e,t]of this._regenSelections){if(t.kind===`user`)continue;let n=this._tree.getSiblingNodes(e).filter(e=>e.kind===`run`);if(n.length<=1)continue;let r=n.at(-1);r&&this._regenSelections.set(e,{kind:`auto`,selectedRunId:r.runId})}}_onTreeAblyMessage(e){let t=N(e),n=t[_],r=t[m];if(!n&&!r){this._emitter.emit(`ably-message`,e);return}r&&this._lastVisibleNodeKeySet.has(r)&&this._emitter.emit(`ably-message`,e)}_onTreeRun(e){if(this._lastVisibleNodeKeySet.has(e.runId)){this._emitter.emit(`run`,e);return}e.type===`start`&&this._isRunStartVisible(e)&&(this._lastVisibleNodeKeySet.add(e.runId),this._emitter.emit(`run`,e))}_isRunStartVisible(e){let{parent:t}=e;if(t===void 0)return!0;let n=this._tree.getNodeByCodecMessageId(t);return n?this._lastVisibleNodeKeySet.has(Y(n)):!0}_visibleChanged(e){if(e.length!==this._lastVisibleNodeKeys.length)return!0;for(let[t,n]of e.entries())if(Y(n)!==this._lastVisibleNodeKeys[t]||n.projection!==this._lastVisibleProjections[t])return!0;return!1}},ze=e=>new Re(e),Be=()=>{},Ve=class{constructor(e){this._views=new Set,this._state=`ready`,this._pendingRunStarts=new Map;let t=ie(e.client,e.codec);if(this._channel=e.client.channels.get(e.channelName,t),this._codec=e.codec,this._clientId=e.clientId,this._logger=(e.logger??De({logLevel:Te.Silent})).withContext({component:`ClientSession`}),this._emitter=new J(this._logger),this._hasAttachedOnce=this._channel.state===`attached`,this._tree=Ne(this._codec,this._logger),this._view=ze({tree:this._tree,channel:this._channel,codec:this._codec,sendDelegate:this._internalSend.bind(this),logger:this._logger,onClose:()=>this._views.delete(this._view)}),this._decoder=this._codec.createDecoder(),this._encoder=this._codec.createEncoder(this._channel,this._clientId===void 0?void 0:{clientId:this._clientId}),this._views.add(this._view),this.tree=this._tree,this.view=this._view,e.messages){let t;for(let n of e.messages){let e=crypto.randomUUID(),r={[_]:e,[b]:`user`};t&&(r[x]=t),this._tree.applyMessage({inputs:[this._codec.createUserMessage(n)],outputs:[]},r),t=e}}this._onMessage=e=>{this._handleMessage(e)},this._onChannelStateChange=e=>{this._handleChannelStateChange(e)},this._channel.on(this._onChannelStateChange)}connect(){return this._state===`closed`?Promise.reject(new t.ErrorInfo(`unable to connect; session is closed`,j.SessionClosed,400)):this._connectPromise?this._connectPromise:(this._logger.trace(`DefaultClientSession.connect();`),this._connectPromise=this._channel.subscribe(this._onMessage).then(()=>{this._logger.debug(`DefaultClientSession.connect(); subscribed and attached`)},e=>{let n=new t.ErrorInfo(`unable to subscribe to channel; ${e instanceof Error?e.message:String(e)}`,j.SessionSubscriptionError,500,e instanceof t.ErrorInfo?e:void 0);throw this._logger.error(`DefaultClientSession.connect(); subscribe failed`),this._emitter.emit(`error`,n),n}),this._connectPromise)}async _requireConnected(e){if(!this._connectPromise)throw new t.ErrorInfo(`unable to ${e}; connect() must be called before ${e}()`,j.InvalidArgument,400);return this._connectPromise}_handleMessage(e){if(this._state!==`closed`)try{if(e.name===`ai-run-end`){let n=N(e);if((n[`run-reason`]??`complete`)===`error`){let e=n[E],r=e===void 0?NaN:Number(e),i=Number.isFinite(r)?r:j.SessionSubscriptionError,a=n[`error-message`]??`agent reported an error`,o=i>=1e4&&i<6e4?Math.floor(i/100):500,s=new t.ErrorInfo(a,i,o);this._logger.error(`ClientSession._handleMessage(); agent error received`,{runId:n[m],invocationId:n[h],code:i}),this._emitter.emit(`error`,s)}}let n=le(this._tree,this._decoder,e);if(n&&(n.type===`start`||n.type===`resume`)){let t=N(e)[T];if(t!==void 0){let e=this._pendingRunStarts.get(t);e&&(this._pendingRunStarts.delete(t),e.resolve(n.runId))}}this._tree.emitAblyMessage(e)}catch(e){let n=e instanceof t.ErrorInfo?e:void 0;this._emitter.emit(`error`,new t.ErrorInfo(`unable to process channel message; ${e instanceof Error?e.message:String(e)}`,j.SessionSubscriptionError,500,n))}}_handleChannelStateChange(e){if(this._state===`closed`)return;let{current:n,resumed:r}=e;if(n===`attached`&&!this._hasAttachedOnce){this._hasAttachedOnce=!0;return}if(!(n===`failed`||n===`suspended`||n===`detached`||n===`attached`&&!r))return;this._logger.error(`ClientSession._handleChannelStateChange(); channel continuity lost`,{current:n,resumed:r,previous:e.previous});let i=new t.ErrorInfo(`unable to deliver events; channel continuity lost (${n}${n===`attached`?`, resumed: false`:``})`,j.ChannelContinuityLost,500,e.reason);this._emitter.emit(`error`,i)}_cleanupFailedSend(e){for(let t of e){let e=this._tree.getNodeByCodecMessageId(t);e?.kind===`input`&&e.serial===void 0&&this._tree.delete(e.codecMessageId)}}createView(){if(this._state===`closed`)throw new t.ErrorInfo(`unable to create view; session is closed`,j.SessionClosed,400);this._logger.trace(`DefaultClientSession.createView();`);let e=ze({tree:this._tree,channel:this._channel,codec:this._codec,sendDelegate:this._internalSend.bind(this),logger:this._logger,onClose:()=>this._views.delete(e)});return this._views.add(e),e}async _internalSend(e,n,r){if(this._state===`closed`||(await this._requireConnected(`send`),this._state===`closed`))throw new t.ErrorInfo(`unable to send; session is closed`,j.SessionClosed,400);let i=this._channel.state;if(i!==`attached`&&i!==`attaching`)throw new t.ErrorInfo(`unable to send; channel is ${i}`,j.ChannelNotReady,400);this._logger.trace(`ClientSession._internalSend();`);let a=n?.runId!==void 0,o=n?.runId,s;n?.parent===void 0&&!n?.forkOf&&(s=r);let c=new Set,u=[];for(let t of e){let e=crypto.randomUUID(),r=t.codecMessageId??crypto.randomUUID();c.add(r);let i=t.kind!==`user-message`&&(t.kind===`regenerate`||t.codecMessageId!==void 0),a=t.parent??(n?.parent===void 0?s:n.parent),l=n?.forkOf,d=t.kind===`regenerate`?t.target:void 0,f=G({role:`user`,runId:o,codecMessageId:r,runClientId:this._clientId,...a!==void 0&&{parent:a},...l!==void 0&&{forkOf:l},...d!==void 0&&{regenerates:d},inputEventId:e});i||this._tree.applyMessage({inputs:[t],outputs:[]},f),u.push({input:t,codecMessageId:r,inputEventId:e,headers:f,isWireOnly:i}),!i&&n?.parent===void 0&&!n?.forkOf&&t.parent===void 0&&(s=r)}let d=u.at(-1);if(d===void 0)throw new t.ErrorInfo(`unable to send; inputs array is empty (include at least one input)`,j.InvalidArgument,400);let f=d.inputEventId,p=d.codecMessageId,m=new Promise((e,t)=>{this._pendingRunStarts.set(p,{resolve:e,reject:t})});return m.catch(()=>{}),await(async()=>{try{for(let e of u)await this._encoder.publishInput(e.input,{extras:{headers:e.headers},messageId:e.codecMessageId,...this._clientId!==void 0&&{clientId:this._clientId}})}catch(e){let n=e instanceof t.ErrorInfo?e:void 0,r=n?.statusCode===401||n?.statusCode===403,i=new t.ErrorInfo(r?`unable to publish events; missing publish capability on the channel`:`unable to publish events; ${e instanceof Error?e.message:String(e)}`,r?j.InsufficientCapability:j.SessionSendFailed,r?401:500,n);throw this._emitter.emit(`error`,i),this._pendingRunStarts.delete(p),a||this._cleanupFailedSend([...c]),i}})(),{inputCodecMessageId:p,runId:m,inputEventId:f,cancel:async()=>{await this._publishCancel({inputCodecMessageId:p,...o!==void 0&&{runId:o}})},optimisticCodecMessageIds:[...c],toInvocation:()=>l.fromJSON({inputEventId:f,sessionName:this._channel.name})}}async cancel(e){return this._publishCancel({runId:e})}async _publishCancel(e){if(this._state===`closed`||(await this._requireConnected(`cancel`),this._state===`closed`))return;this._logger.debug(`ClientSession._publishCancel();`,{runId:e.runId,inputCodecMessageId:e.inputCodecMessageId});let t={[g]:crypto.randomUUID()};e.runId!==void 0&&(t[m]=e.runId),e.inputCodecMessageId!==void 0&&(t[T]=e.inputCodecMessageId),await this._channel.publish({name:D,extras:{ai:{transport:t}}})}on(e,t){if(this._state===`closed`)return Be;let n=t;return this._emitter.on(e,n),()=>{this._emitter.off(e,n)}}async close(){if(this._state!==`closed`){this._state=`closed`,this._logger.info(`ClientSession.close();`),this._connectPromise&&this._channel.unsubscribe(this._onMessage),this._channel.off(this._onChannelStateChange),this._emitter.off();for(let e of this._views)e.close();if(this._views.clear(),this._pendingRunStarts.size>0){let e=new t.ErrorInfo(`unable to await run-start; session closed`,j.SessionClosed,400);for(let t of this._pendingRunStarts.values())t.reject(e);this._pendingRunStarts.clear()}try{await this._encoder.close()}catch{}if(this._connectPromise)try{await this._channel.detach()}catch(e){this._logger.debug(`ClientSession.close(); channel detach failed`,{error:e})}}}},He=e=>new Ve(e),Ue=class{constructor(e,t={}){this._trackers=new Map,this._pending=[],this._closed=!1,this._writer=e,this._defaultClientId=t.clientId,this._defaultExtras=t.extras,this._onMessageHook=t.onMessage??(()=>{}),this._logger=t.logger?.withContext({component:`EncoderCore`})}async publishDiscrete(e,t){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.publishDiscrete();`,{name:e.name});let n=this._buildDiscreteMessage(e,t);return this._writer.publish(n)}async publishDiscreteBatch(e,t){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.publishDiscreteBatch();`,{count:e.length});let n=e.map(e=>this._buildDiscreteMessage(e,t,!0));return this._writer.publish(n)}async startStream(e,n,r){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.startStream();`,{name:n.name,streamId:e});let i=this._buildTransport(n.transportHeaders,r);i[u]=`true`,i[d]=`streaming`,i[f]=e;let a=n.codecHeaders??{},o=this._resolveClientId(r),s={name:n.name,data:n.data,extras:{ai:this._aiExtras(i,a)},...o?{clientId:o}:{}};this._invokeOnMessage(s);let c=(await this._writer.publish(s)).serials[0];if(!c)throw new t.ErrorInfo(`unable to start stream; no serial returned for stream '${n.name}' (streamId: ${e})`,j.BadRequest,400);this._trackers.set(e,{serial:c,name:n.name,streamId:e,accumulated:n.data,persistentTransport:i,persistentCodec:a,cancelled:!1}),this._logger?.debug(`DefaultEncoderCore.startStream(); stream started`,{name:n.name,streamId:e,serial:c})}appendStream(e,n){this._assertNotClosed();let r=this._trackers.get(e);if(!r)throw new t.ErrorInfo(`unable to append to stream; no active stream for streamId '${e}'`,j.InvalidArgument,400);r.accumulated+=n;let i={serial:r.serial,data:n,extras:{ai:this._aiExtras({...r.persistentTransport},{...r.persistentCodec})}};this._invokeOnMessage(i);let a=this._writer.appendMessage(i);this._pending.push({promise:a,streamId:e})}async closeStream(e,n){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.closeStream();`,{streamId:e});let r=this._trackers.get(e);if(!r)throw new t.ErrorInfo(`unable to close stream; no active stream for streamId '${e}'`,j.InvalidArgument,400);r.accumulated+=n.data;let{transport:i,codec:a}=this._buildClosing(r,n);i[d]=`complete`;let o={serial:r.serial,data:n.data,extras:{ai:this._aiExtras(i,a)}};this._invokeOnMessage(o);let s=this._writer.appendMessage(o);this._pending.push({promise:s,streamId:e}),await this._flushPending(),this._logger?.debug(`DefaultEncoderCore.closeStream(); stream closed`,{streamId:e})}async cancelStream(e,n){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.cancelStream();`,{streamId:e});let r=this._trackers.get(e);if(!r)throw new t.ErrorInfo(`unable to cancel stream; no active stream for streamId '${e}'`,j.InvalidArgument,400);r.cancelled=!0;let{transport:i,codec:a}=this._buildClosing(r,void 0,n);i[d]=`cancelled`;let o={serial:r.serial,data:``,extras:{ai:this._aiExtras(i,a)}};this._invokeOnMessage(o);let s=this._writer.appendMessage(o);this._pending.push({promise:s,streamId:e}),await this._flushPending(),this._logger?.debug(`DefaultEncoderCore.cancelStream(); stream cancelled`,{streamId:e})}async cancelAllStreams(e){this._assertNotClosed(),this._logger?.trace(`DefaultEncoderCore.cancelAllStreams();`,{streamCount:this._trackers.size});for(let t of this._trackers.values()){t.cancelled=!0;let{transport:n,codec:r}=this._buildClosing(t,void 0,e);n[d]=`cancelled`;let i={serial:t.serial,data:``,extras:{ai:this._aiExtras(n,r)}};this._invokeOnMessage(i);let a=this._writer.appendMessage(i);this._pending.push({promise:a,streamId:t.streamId})}await this._flushPending()}async _flushPending(){if(this._flushPromise)return this._flushPromise;let e=this._pending;if(this._pending=[],e.length!==0){this._logger?.trace(`DefaultEncoderCore._flushPending();`,{count:e.length}),this._flushPromise=this._doFlush(e);try{await this._flushPromise}finally{this._flushPromise=void 0}}}async _doFlush(e){let n=await Promise.allSettled(e.map(async e=>e.promise)),r=new Set;for(let[t,i]of n.entries()){let n=e[t];n&&i.status===`rejected`&&r.add(n.streamId)}if(r.size===0){this._logger?.debug(`DefaultEncoderCore._flushPending(); all appends succeeded`);return}this._logger?.warn(`DefaultEncoderCore._flushPending(); recovering failed appends`,{failedStreams:[...r]});let i=[];for(let e of r){let t=this._trackers.get(e);if(!t)continue;let n=t.cancelled?`cancelled`:`complete`,r={serial:t.serial,data:t.accumulated,extras:{ai:this._aiExtras({...t.persistentTransport,[d]:n},{...t.persistentCodec})}};try{await this._writer.updateMessage(r)}catch(t){i.push({streamId:e,error:t})}}if(i.length>0){let e=i.map(e=>e.streamId).join(`, `);throw this._logger?.error(`DefaultEncoderCore._flushPending(); recovery failed`,{failedStreams:e}),new t.ErrorInfo(`unable to flush pending appends; recovery failed for stream(s): ${e}`,j.EncoderRecoveryFailed,500)}}async close(){if(!this._closed){this._logger?.trace(`DefaultEncoderCore.close();`),this._closed=!0;try{await this._flushPending()}finally{this._trackers.clear()}this._logger?.debug(`DefaultEncoderCore.close(); encoder closed`)}}_invokeOnMessage(e){try{this._onMessageHook(e)}catch(e){this._logger?.error(`DefaultEncoderCore._invokeOnMessage(); hook threw`,{error:e})}}_assertNotClosed(){if(this._closed)throw new t.ErrorInfo(`unable to write to encoder; encoder has been closed`,j.InvalidArgument,400)}_resolveClientId(e){return e?.clientId??this._defaultClientId}_buildTransport(e,t){let n={...I(this._defaultExtras?.headers,t?.extras?.headers),...e};return t?.messageId!==void 0&&(n[_]=t.messageId),n}_aiExtras(e,t){return Object.keys(t).length>0?{transport:e,codec:t}:{transport:e}}_buildDiscreteMessage(e,t,n=!1){let r=this._buildTransport(e.transportHeaders,t);r[u]=`false`,n&&(r[p]=`true`);let i=this._resolveClientId(t),a={name:e.name,data:e.data,extras:{ai:this._aiExtras(r,e.codecHeaders??{}),...e.ephemeral?{ephemeral:!0}:{}},...i?{clientId:i}:{}};return this._invokeOnMessage(a),a}_buildClosing(e,t,n){let r=I(this._defaultExtras?.headers,n?.extras?.headers);return{transport:{...e.persistentTransport,...r,...t?.transportHeaders},codec:{...e.persistentCodec,...t?.codecHeaders}}}},We=(e,t={})=>new Ue(e,t),Ge=class{constructor(e,t={}){this._serialState=new Map,this._hooks=e,this._onStreamUpdate=t.onStreamUpdate,this._onStreamDelete=t.onStreamDelete,this._logger=t.logger?.withContext({component:`DecoderCore`})}decode(e){let t=e.action;switch(this._logger?.trace(`DefaultDecoderCore.decode();`,{action:t,serial:e.serial,name:e.name}),t){case`message.create`:{let t=this._toPayload(e);return t.transportHeaders?.stream===`true`?this._decodeStreamedCreate(t,e.serial):this._hooks.decodeDiscrete(t)}case`message.append`:return this._decodeAppend(e);case`message.update`:return this._decodeUpdate(e);case`message.delete`:return this._decodeDelete(e);default:return[]}}_toPayload(e){return{name:e.name??``,data:e.data,transportHeaders:N(e),codecHeaders:P(e)}}_stringData(e){return typeof e.data==`string`?e.data:``}_invokeOnStreamUpdate(e){if(this._onStreamUpdate)try{this._onStreamUpdate(e)}catch(e){this._logger?.error(`DefaultDecoderCore._invokeOnStreamUpdate(); callback threw`,{error:e})}}_invokeOnStreamDelete(e,t){if(this._onStreamDelete)try{this._onStreamDelete(e,t)}catch(e){this._logger?.error(`DefaultDecoderCore._invokeOnStreamDelete(); callback threw`,{error:e})}}_decodeStreamedCreate(e,t){if(!t)return[];let n=e.transportHeaders?.[`stream-id`]??``,r={name:e.name,streamId:n,accumulated:``,codecHeaders:{...e.codecHeaders},transportHeaders:{...e.transportHeaders},closed:!1};return this._serialState.set(t,r),this._logger?.debug(`DefaultDecoderCore._decodeStreamedCreate(); new stream`,{name:e.name,streamId:n,serial:t}),this._hooks.buildStartEvents(r)}_decodeAppend(e){let t=e.serial;if(!t)return[];let n=this._serialState.get(t);if(!n)return this._decodeUpdate(e);let r=N(e),i=P(e),a=typeof e.data==`string`?e.data:``,o=r[d],s=[];return a.length>0&&(n.accumulated+=a,s.push(...this._hooks.buildDeltaEvents(n,a))),o===`complete`&&!n.closed?(n.closed=!0,s.push(...this._hooks.buildEndEvents(n,i)),this._logger?.debug(`DefaultDecoderCore._decodeAppend(); stream complete`,{streamId:n.streamId})):o===`cancelled`&&!n.closed&&(n.closed=!0,this._logger?.debug(`DefaultDecoderCore._decodeAppend(); stream cancelled`,{streamId:n.streamId})),s}_decodeUpdate(e){let t=e.serial;if(!t)return[];let n=this._toPayload(e),r=n.transportHeaders??{},i=n.codecHeaders??{},a=r[u]===`true`,o=r[d],s=this._serialState.get(t);if(!s)return this._decodeFirstContact(n,a,o,t);let c=this._stringData(e);if(c.startsWith(s.accumulated)){let e=c.slice(s.accumulated.length),t=[];return e.length>0&&(s.accumulated=c,t.push(...this._hooks.buildDeltaEvents(s,e))),o===`complete`&&!s.closed?(s.closed=!0,t.push(...this._hooks.buildEndEvents(s,i))):o===`cancelled`&&!s.closed&&(s.closed=!0),t}return s.accumulated=c,s.codecHeaders={...i},s.transportHeaders={...r},this._invokeOnStreamUpdate(s),[]}_decodeFirstContact(e,t,n,r){if(!t)return this._hooks.decodeDiscrete(e);let i=e.transportHeaders?.[`stream-id`]??``,a=e.codecHeaders??{},o=typeof e.data==`string`?e.data:``;this._logger?.debug(`DefaultDecoderCore._decodeFirstContact(); first-contact stream`,{name:e.name,streamId:i,serial:r});let s={name:e.name,streamId:i,accumulated:o,codecHeaders:{...a},transportHeaders:{...e.transportHeaders},closed:n===`complete`||n===`cancelled`};this._serialState.set(r,s);let c=this._hooks.buildStartEvents(s);return o.length>0&&c.push(...this._hooks.buildDeltaEvents(s,o)),n===`complete`&&c.push(...this._hooks.buildEndEvents(s,a)),c}_decodeDelete(e){let t=e.serial;if(!t)return[];let n=this._serialState.get(t);return this._invokeOnStreamDelete(t,n),n&&(n.accumulated=``,n.closed=!0),this._logger?.debug(`DefaultDecoderCore._decodeDelete();`,{serial:t}),[]}},Ke=(e,t={})=>new Ge(e,t),qe=class{constructor(e){this._emitted=new Map,this._phases=e}ensurePhases(e,t){let n=this._getOrCreate(e),r=[];for(let e of this._phases)n.has(e.key)||(n.add(e.key),r.push(...e.build(t)));return r}markEmitted(e,t){this._getOrCreate(e).add(t)}resetPhase(e,t){this._emitted.get(e)?.delete(t)}clearScope(e){this._emitted.delete(e)}_getOrCreate(e){let t=this._emitted.get(e);return t||(t=new Set,this._emitted.set(e,t)),t}};e.EVENT_CANCEL=D,e.EVENT_RUN_END=A,e.EVENT_RUN_START=O,e.ErrorCode=j,e.EventEmitter=J,e.HEADER_CODEC_MESSAGE_ID=_,e.HEADER_ERROR_CODE=E,e.HEADER_ERROR_MESSAGE=ee,e.HEADER_FORK_OF=S,e.HEADER_INPUT_CLIENT_ID=y,e.HEADER_MSG_REGENERATE=C,e.HEADER_PARENT=x,e.HEADER_ROLE=b,e.HEADER_RUN_CLIENT_ID=v,e.HEADER_RUN_ID=m,e.HEADER_RUN_REASON=w,e.HEADER_STATUS=d,e.HEADER_STREAM=u,e.HEADER_STREAM_ID=f,e.Invocation=l,e.LogLevel=Te,e.buildTransportHeaders=G,e.consoleLogger=Ee,e.createAgentSession=Se,e.createClientSession=He,e.createDecoderCore=Ke,e.createEncoderCore=We,e.createLifecycleTracker=e=>new qe(e),e.errorInfoIs=ne,e.getCodecHeaders=P,e.getTransportHeaders=N,e.headerReader=V,e.headerWriter=H,e.makeLogger=De,e.mergeHeaders=I,e.stripUndefined=B});
2
2
  //# sourceMappingURL=ably-ai-transport.umd.cjs.map