eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 3.59 kB
JavaScript
import{createLogger,logError}from"#internal/logging.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{requestWorkflowTurnCancellation}from"#execution/workflow-runtime.js";import{deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-store.js";import{cancelRemoteAgentTurn,isRetryableRemoteAgentCancelError,resolveRemoteAgentForAction}from"#subagents/remote-dispatch.js";import{cancelWorkflowToolRun}from"#execution/tools/workflow/cancel.js";import{getWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{getAgentHandleStore}from"#subagents/handles/store.js";import{getDynamicSubagentSelection}from"#context/dynamic-subagent-lifecycle.js";const log=createLogger(`execution.cancel-descendant-turns`);async function cancelDescendantTurnsStep(e){"use step";let t,n;try{let r=await readDurableSession(e.sessionState);n=getWorkflowToolRuns(r.state);let i=new Set(n.map(e=>e.runId));t=(getAgentHandleStore(r.state)?.handles??[]).filter(e=>e.phase===`running`||e.phase===`claimed`&&i.has(e.ownerId))}catch(t){logError(log,`failed to read pending descendants during cancellation`,t,{sessionId:e.sessionState.sessionId});return}if(await Promise.all(n.map(e=>cancelWorkflowToolRun(e,`The turn that called the tool was cancelled.`))),t.length===0)return;let r,getRemoteContext=()=>r??=deserializeContext(e.serializedContext).then(e=>({ctx:e,registry:e.require(BundleKey).subagentRegistry.subagentsByNodeId}));await Promise.all(t.map(e=>e.address.kind===`agent/remote`?cancelRemoteDescendant({handle:e,remoteContext:getRemoteContext()}):cancelLocalDescendant({handle:e})))}async function cancelLocalDescendant(e){let{handle:t}=e;try{let e=await requestCancellationWithRetry({request:()=>requestWorkflowTurnCancellation({sessionId:t.address.sessionId}),shouldRetryError:()=>!1});e.status!==`accepted`&&log.warn(`descendant cancel was never accepted; the child may run to completion`,{callId:readHandleCallId(t),childSessionId:t.address.sessionId,finalStatus:e.status,subagentName:t.identity.name})}catch(e){logError(log,`failed to cancel local descendant turn`,e,{callId:readHandleCallId(t),childSessionId:t.address.sessionId,subagentName:t.identity.name})}}async function cancelRemoteDescendant(e){let{handle:t}=e;if(t.address.kind!==`agent/remote`)return;let n=t.address.url;try{let{ctx:r,registry:i}=await e.remoteContext,a=getDynamicSubagentSelection(r,t.identity.nodeId),o={...await resolveRemoteAgentForAction({dynamicRemoteAgent:a?.kind===`remote`?a.remoteAgent:void 0,nodeId:t.identity.nodeId,remoteAgentName:t.identity.name,registry:i}),url:n},s=await requestCancellationWithRetry({request:()=>cancelRemoteAgentTurn({remote:o,sessionId:t.address.sessionId}),shouldRetryError:isRetryableRemoteAgentCancelError});s.status!==`accepted`&&log.warn(`remote descendant cancel was never accepted; the child may run to completion`,{callId:readHandleCallId(t),childSessionId:t.address.sessionId,finalStatus:s.status,remoteAgentName:t.identity.name})}catch(e){logError(log,`failed to cancel remote descendant turn`,e,{callId:readHandleCallId(t),childSessionId:t.address.sessionId,remoteAgentName:t.identity.name})}}function readHandleCallId(e){return e.phase===`running`?e.operation.callId:e.callId}async function requestCancellationWithRetry(e){let t=250,n={status:`no_active_turn`};for(let r=1;r<=8;r+=1){try{if(n=await e.request(),n.status===`accepted`||r===8)return n}catch(t){if(!e.shouldRetryError(t)||r===8)throw t}await new Promise(e=>setTimeout(e,t)),t=Math.min(t*2,1500)}return n}export{cancelDescendantTurnsStep};