eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 3.29 kB
JavaScript
import{createHook}from"#compiled/@workflow/core/index.js";import{closeHookIterator,disposeHook}from"#execution/hook-ownership.js";import{forwardTurnDeliveryStep}from"#execution/forward-turn-delivery-step.js";import{rebuildSerializableError}from"#execution/workflow-errors.js";var TurnControlReceiver=class{bufferedDeliveries;control;controlIterator;deliveryHook;pendingControl=null;constructor(t){this.bufferedDeliveries=t.bufferedDeliveries,this.control=createHook({token:t.token}),this.controlIterator=this.control[Symbol.asyncIterator](),this.deliveryHook=t.deliveryHook}get token(){return this.control.token}async dispose(){await closeHookIterator(this.controlIterator),await disposeHook(this.control)}async waitForAction(){for(;;){let e=await this.nextControl(`Turn control hook closed before delivering a result.`),t=this.readTerminalControl(e);if(t!==void 0)return t;if(e.kind===`turn-delivery-request`){let t=await this.serviceDeliveryRequest(e);if(t!==void 0)return t}}}bufferTurnDeliveries(e){e.bufferedDeliveries!==void 0&&this.bufferedDeliveries.unshift(...e.bufferedDeliveries)}consumeControl(){this.pendingControl=null}getControlPromise(){return this.pendingControl??=this.controlIterator.next(),this.pendingControl}async nextControl(e){for(;;){let t=await this.getControlPromise();if(this.consumeControl(),t.done)throw Error(e);let n=t.value;if(n.kind===`turn-error`)throw rebuildSerializableError(n.error);if(n.kind===`turn-continuation-token`){await this.deliveryHook.rekey(n.continuationToken);continue}return n}}readTerminalControl(e){if(e.kind===`turn-error`)throw rebuildSerializableError(e.error);if(e.kind===`turn-result`)return this.bufferTurnDeliveries(e),e.action}async serviceDeliveryRequest(e){await this.deliveryHook.rekey(e.continuationToken);let t=this.bufferedDeliveries.shift();for(;t===void 0;){let n=await Promise.race([this.getControlPromise().then(e=>({kind:`control`,value:e})),this.deliveryHook.next().then(e=>({kind:`delivery`,value:e}))]);if(n.kind===`control`){if(this.consumeControl(),n.value.done)throw Error(`Turn control hook closed during a delivery request.`);if(n.value.value.kind===`turn-continuation-token`){await this.deliveryHook.rekey(n.value.value.continuationToken);continue}let t=this.readTerminalControl(n.value.value);if(t!==void 0)return t;if(n.value.value.kind===`turn-delivery-cancelled`&&n.value.value.requestId===e.requestId)return;continue}if(n.value.done)throw Error(`Session delivery hook closed during a turn delivery request.`);this.deliveryHook.consumeNext(),n.value.value.kind===`deliver`&&(t=n.value.value)}try{await forwardTurnDeliveryStep({inboxToken:e.inboxToken,payload:{delivery:t,kind:`driver-delivery`,requestId:e.requestId}})}catch(e){if(!(e instanceof Error&&e.name===`HookNotFoundError`))throw e}return await this.awaitForwardedDelivery(e.requestId,t)}async awaitForwardedDelivery(e,t){for(;;){let n=await this.nextControl(`Turn control hook closed before resolving a forwarded delivery.`);if(n.kind===`turn-delivery-accepted`){if(n.requestId===e)return;continue}if(n.kind===`turn-delivery-cancelled`&&n.requestId===e){this.bufferedDeliveries.unshift(t);return}n.kind===`turn-result`&&this.bufferedDeliveries.unshift(t);let r=this.readTerminalControl(n);if(r!==void 0)return r}}};export{TurnControlReceiver};