eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 7.07 kB
JavaScript
import{createEventDeduper}from"#protocol/event-dedupe.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{readNdjsonStream}from"#client/ndjson.js";import{readMessageStreamVersion}from"#client/stream-version.js";var SubagentPump=class{#e;#t;#n;#r;#i=new Map;#a=new Map;#o=new Map;#s=new Map;#c=new Map;constructor(e){this.#e=e.client,this.#t=e.view,this.#n=e.formatActionResultError,this.#r=e.onToolCompleted}begin(e){let t=e.data.callId,n=this.#i.get(t);n===void 0?this.#i.set(t,{name:e.data.name,childSessionId:e.data.childSessionId,parentTurnId:e.data.turnId,background:!1,status:`open`,childStreamPath:e.data.childStreamPath,childStreamIndex:this.#o.get(e.data.childSessionId)??0,steps:new Map,currentSectionKey:null,nextSectionKey:0,tools:new Map,seenChildEvents:createEventDeduper()}):n.name=e.data.name,this.#t?.markChildToolCallId(t),(n===void 0||n.status===`open`)&&(this.#t?.begin({callId:t,name:e.data.name}),n===void 0&&this.#l(t))}settle(e){this.#f(e,!1)}background(e){let t=this.#i.get(e);t!==void 0&&(t.background=!0,t.status!==`authoritative`&&this.#t?.background({callId:e}))}abortAll(){for(let e of this.#a.values())e.abort();this.#a.clear(),this.#i.clear(),this.#o.clear(),this.#s.clear(),this.#c.clear()}settleCancelledTurn(e){for(let[t,n]of this.#i)n.parentTurnId!==e||n.background||(this.#f(t,!0),this.#a.get(t)?.abort(),this.#a.delete(t))}#l(e){let t=this.#i.get(e);if(t===void 0||t.status===`authoritative`)return;let n=this.#s.get(t.childSessionId);if(n===void 0){t.childStreamIndex=this.#o.get(t.childSessionId)??0,this.#s.set(t.childSessionId,e),this.#u(e);return}if(n===e)return;let r=this.#c.get(t.childSessionId)??[];r.includes(e)||r.push(e),this.#c.set(t.childSessionId,r)}#u(e){if(this.#a.has(e))return;let t=this.#e;if(!t)return;let n=this.#i.get(e);if(n===void 0||n.status===`authoritative`)return;let r=new AbortController;this.#a.set(e,r),(async()=>{let i=100;try{for(;!r.signal.aborted&&n.status!==`authoritative`;){let a=!1;try{let i=await t.fetch(streamPathAt(n.childStreamPath,n.childStreamIndex),{cache:`no-store`,signal:r.signal});if(!i.ok||i.body===null)throw await i.body?.cancel().catch(()=>{}),Error(`Child stream returned ${i.status}.`);for await(let t of readNdjsonStream(i.body,{streamVersion:readMessageStreamVersion(i.headers)})){if(r.signal.aborted)return;a=!0,n.childStreamIndex+=1,this.#o.set(n.childSessionId,n.childStreamIndex);let i=this.#h(e,t);if(i!==void 0&&await i,isCurrentTurnBoundaryEvent(t)){if(t.type===`session.waiting`&&hasPendingChildApproval(n))continue;this.#f(e,!0);return}}}catch{if(r.signal.aborted)return}i=a?100:Math.min(i*2,2e3),await abortableDelay(i,r.signal)}}finally{r.abort(),this.#a.get(e)===r&&this.#a.delete(e)}})()}#d(e,t,n){let r=t.tools.get(n.childCallId),i=r??{toolName:n.toolName,input:n.input,status:n.status};if(r){let e=r.status===`done`||r.status===`failed`||r.status===`rejected`;if(n.status===`approval-requested`&&!e)r.status=n.status;else{let e={preparing:0,"approval-requested":1,executing:2,done:3,failed:3,rejected:3};e[n.status]>e[r.status]&&(r.status=n.status)}n.input!==void 0&&(r.input=n.input)}else t.tools.set(n.childCallId,i);this.#t?.markChildToolCallId(n.childCallId),this.#t?.upsertTool({callId:e,subagentName:t.name,childCallId:n.childCallId,toolName:i.toolName,input:i.input,status:i.status})}#f(e,t){let n=this.#i.get(e);if(n&&n.status!==`authoritative`&&(t||n.status!==`provisional`)){n.status=t?`authoritative`:`provisional`;for(let[t,r]of n.steps)r.finalized||(r.finalized=!0,this.#t?.upsertStep({callId:e,subagentName:n.name,sectionKey:t,reasoning:r.reasoning,message:r.message,finalized:!0}));n.currentSectionKey=null,this.#m(e,n),this.#t?.complete({authoritative:t,callId:e}),t&&this.#p(e,n.childSessionId)}}#p(e,t){let n=(this.#c.get(t)??[]).filter(t=>t!==e);if(this.#s.get(t)!==e){n.length===0?this.#c.delete(t):this.#c.set(t,n);return}for(this.#s.delete(t);n.length>0;){let e=n.shift(),r=this.#i.get(e);if(r!==void 0&&r.status!==`authoritative`){n.length===0?this.#c.delete(t):this.#c.set(t,n),r.childStreamIndex=this.#o.get(t)??0,this.#s.set(t,e),this.#u(e);return}}this.#c.delete(t)}#m(e,t){for(let[n,r]of t.tools)r.status===`preparing`&&(t.tools.delete(n),this.#t?.removeTool({callId:e,childCallId:n}))}#h(e,t){let n=this.#i.get(e);if(!n||!n.seenChildEvents.admit(t))return;n.status===`provisional`&&(n.status=`open`,this.#t?.begin({callId:e,name:n.name}));let r=this.#t,emit=(t,i)=>{r?.upsertStep({callId:e,subagentName:n.name,sectionKey:t,reasoning:i.reasoning,message:i.message,finalized:i.finalized})},finalizeCurrent=()=>{if(n.currentSectionKey===null)return;let e=n.steps.get(n.currentSectionKey);e&&(e.finalized=!0,emit(n.currentSectionKey,e)),n.currentSectionKey=null};switch(t.type){case`reasoning.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.reasoning+=t.data.reasoningDelta,emit(e,r);break}case`reasoning.completed`:break;case`message.appended`:{let{key:e,step:r}=openCurrentSubagentSection(n);r.message+=t.data.messageDelta,emit(e,r);break}case`message.completed`:{let{key:e,step:r}=openCurrentSubagentSection(n);t.data.message!==null&&r.message.length===0&&(r.message=t.data.message),r.finalized=!0,emit(e,r),n.currentSectionKey=null;break}case`step.completed`:finalizeCurrent(),this.#m(e,n);break;case`actions.requested`:finalizeCurrent();for(let r of t.data.actions)r.kind===`tool-call`&&this.#d(e,n,{childCallId:r.callId,toolName:r.toolName,input:r.input,status:`executing`});break;case`input.requested`:finalizeCurrent();for(let r of t.data.requests)r.action.kind===`tool-call`&&this.#d(e,n,{childCallId:r.action.callId,toolName:r.action.toolName,input:r.action.input,status:`approval-requested`});break;case`action.result`:{let i=t.data.result;if(i.kind!==`tool-result`)break;let a=n.tools.get(i.callId);if(!a)break;switch(t.data.status){case`completed`:a.status=`done`,a.output=i.output;break;case`failed`:a.status=`failed`,a.errorText=this.#n(t);break;case`rejected`:a.status=`rejected`,a.errorText=this.#n(t)}let o={callId:e,subagentName:n.name,childCallId:i.callId,toolName:a.toolName,input:a.input,status:a.status};if(a.output!==void 0&&(o.output=a.output),a.errorText!==void 0&&(o.errorText=a.errorText),r?.upsertTool(o),t.data.status===`completed`)return this.#r?.(a.toolName,i.output);break}}}};function hasPendingChildApproval(e){return[...e.tools.values()].some(e=>e.status===`approval-requested`)}function streamPathAt(e,t){return t===0?e:`${e}${e.includes(`?`)?`&`:`?`}startIndex=${t}`}async function abortableDelay(e,t){t.aborted||await new Promise(n=>{let onAbort=()=>{clearTimeout(r),n()},r=setTimeout(()=>{t.removeEventListener(`abort`,onAbort),n()},e);r.unref?.(),t.addEventListener(`abort`,onAbort,{once:!0})})}function openCurrentSubagentSection(e){e.currentSectionKey===null&&(e.currentSectionKey=e.nextSectionKey++,e.steps.set(e.currentSectionKey,{reasoning:``,message:``,finalized:!1}));let t=e.steps.get(e.currentSectionKey);if(!t)throw Error(`invariant: subagent section state missing for current key`);return{key:e.currentSectionKey,step:t}}export{SubagentPump};