eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 2.66 kB
JavaScript
import{sessionInboxHookToken}from"#execution/session-inbox/address.js";import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook}from"#execution/hook-ownership.js";import{releaseSessionHooksStep}from"#execution/session-inbox/release-step.js";function isInterrupt(e){return e.kind===`cancel`||e.kind===`reset`||e.kind===`session-timeout`}function createSessionInbox(e){let t=[],n=[],r=new Set,i=new Set,a=new Set,o,notify=()=>{for(let e of r)e();r.clear()},wait=()=>new Promise(e=>r.add(e)),closed=()=>t.every(e=>e.closed||e.stopping),pump=async e=>{let t=e.hook[Symbol.asyncIterator]();try{for(;!e.stopping;){let e=await t.next();if(e.done)break;if(n.push(e.value),e.value.kind===`send`||e.value.kind===`deliver`)for(let t of a)t(e.value);if(isInterrupt(e.value))for(let t of i)t(e.value);notify()}}catch(t){e.stopping||(o={error:t})}finally{e.closed=!0,notify()}},stop=async()=>{let e=t.splice(0);for(let t of e)t.stopping=!0;notify(),await Promise.all(e.map(({hook:e})=>disposeHook(e)));let r=n.splice(0);return notify(),r},claimSessionHook=async n=>{if(!n)throw Error(`A session alias requires a nonempty continuation token.`);let r=t.find(e=>e.token===n);if(r!==void 0)return await r.registered;if(t.length>=256)throw Error(`A session may claim at most 256 addresses.`);let i={token:n,hook:createHook({token:sessionInboxHookToken(n),metadata:{sessionId:e}}),stopping:!1,closed:!1};t.push(i);try{i.registered=claimHookOwnership(i.hook),await i.registered,pump(i)}catch(e){throw t.splice(t.indexOf(i),1),e}};return{get claimedTokens(){return t.map(({token:e})=>e)},claimSessionHook,async claimSessionHooks(e){let t=await Promise.allSettled([...new Set(e)].map(claimSessionHook));for(let e of t)if(e.status===`rejected`)throw e.reason},async next(){for(;;){if(o!==void 0)throw o.error;if(n.length>0)return n.shift();if(closed())return;await wait()}},drain(){if(o!==void 0)throw o.error;return n.splice(0)},hasPending(){if(o!==void 0)throw o.error;return n.length>0},onInterrupt(e){return i.add(e),()=>i.delete(e)},onDelivery(e){a.add(e);for(let t of n)(t.kind===`send`||t.kind===`deliver`)&&e(t);return()=>a.delete(e)},restore(e){if(t.length===0)throw Error(`Cannot restore session commands before reclaiming the session hooks.`);n.unshift(...e),notify()},async dispose(){await stop()},async release(){return t.length>0&&await releaseSessionHooksStep({ownerRunId:getWorkflowMetadata().workflowRunId,tokens:t.map(({hook:e})=>e.token)}),await stop()}}}function isWorkflowMessage(e){return e.kind===`report`||e.kind===`request`||e.kind===`outcome`}export{createSessionInbox,isInterrupt,isWorkflowMessage};