eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 10.3 kB
JavaScript
import{createHook,getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{claimHookOwnership,disposeHook,isHookConflictError}from"#execution/hook-ownership.js";import{isInboxSubagentResultFromRecordedWorkflowToolRun,isInboxToolResultFromRecordedWorkflowToolRun}from"#harness/workflow-tool-runs.js";import{activeTurnId}from"#harness/active-turn-id.js";import{migrateTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{cancelAllIndexedSessionTasksStep}from"#execution/cancel-indexed-session-tasks-step.js";import{turnStep}from"#execution/workflow-steps.js";import{routeDeliverToChildren}from"#execution/route-child-delivery.js";import{runProxySubagentEventStep}from"#subagents/event-proxy-step.js";import{createChannelReader,raceChannelReads}from"#execution/tools/workflow/owner-channels.js";import{openWorkflowToolRunOwnerInbox}from"#execution/tools/workflow/owner.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{acknowledgeDelegatedTasksStep}from"#execution/tasks/parent/delegate.js";import{normalizeSerializableError}from"#execution/workflow-errors.js";import{sendTurnControlStep}from"#execution/turn-control-protocol.js";import{findRunningAgentHandle,isInboxSubagentResultFromRunningHandle}from"#subagents/handles/query.js";import{cancelDescendantTurnsStep}from"#execution/cancel-descendant-turns-step.js";import{dispatchCoordinationStep}from"#execution/coordination-dispatch-step.js";import{createTurnCancellationControl}from"#execution/turn-cancellation-control.js";import{TurnExecutionCursor}from"#execution/turn-execution-cursor.js";import{resolveRuntimeActionResultsForCallIds}from"#runtime/actions/results.js";import{handleWorkflowToolRunMessage}from"#execution/turn-workflow-tool-run.js";const TASK_MODE_WAIT_ERROR_MESSAGE="Task mode cannot wait for follow-up input (`next: null`).";async function turnWorkflow(e){"use workflow";let t=migrateTurnWorkflowInput(e);return t.driverCapabilities?.turnInbox===!0?runTurnOwnedWorkflow(t):runLegacyTurnWorkflow(t)}async function runTurnOwnedWorkflow(e,t){let n=createHook({token:`${e.completionToken}:inbox`}),r=createChannelReader(`inbox`,n),i=e.initialStep,a=new TurnExecutionCursor({controlToken:e.completionToken,parentWritable:e.stepInput.parentWritable,serializedContext:i?.beforeStep.serializedContext??e.stepInput.serializedContext,sessionState:i?.beforeStep.sessionState??e.stepInput.sessionState}),o=0,nextDeliveryRequestId=()=>`${n.token}:delivery:${String(o++)}`,s=[],c=e.stepInput.input,l=!1,u;try{try{await claimHookOwnership(n),l=!0}catch(e){if(isHookConflictError(e))return;throw e}let o=openWorkflowToolRunOwnerInbox(),d=[o.reader,r];for(e.driverCapabilities?.cancelledTurnSettle===!0&&(u=await createTurnCancellationControl({controlToken:e.completionToken,expectedTurnId:activeTurnId(a.sessionState.emissionState),initialPayload:e.initialCancellation})),t?.();;){let t=i?.beforeStep??{serializedContext:a.serializedContext,sessionState:a.sessionState},r=i?.result??await turnStep(a.createStepInput(c,u?.signal));i=void 0;let l=r.action===`dispatch-workflow-tasks`?r.pendingTaskCallIds:r.action===`park`?r.pendingCoordinationCallIds:void 0,f=(r.backgroundTasks?.length??0)>0;if(f){if(r.backgroundTaskState===void 0)throw Error(`Background tasks were returned without their committed session state.`);await a.adopt({serializedContext:r.backgroundTaskContext??t.serializedContext,sessionState:r.backgroundTaskState}),await acknowledgeDelegatedTasksStep({tasks:r.backgroundTasks??[]})}if(r.action===`cancelled`){await a.adopt({serializedContext:r.serializedContext,sessionState:r.backgroundTaskState??r.sessionState}),await finishCancelledTurn({bufferedDeliveries:s,cancellation:u,cursor:a});return}if(u?.signal.aborted===!0&&(l===void 0||f)){await a.adopt({serializedContext:r.serializedContext,sessionState:r.backgroundTaskState??r.sessionState}),await finishCancelledTurn({bufferedDeliveries:s,cancellation:u,cursor:a});return}if(r.action===`done`){await u?.dispose(),await a.finish(r,{kind:`done`,output:r.output??``,isError:r.isError,usage:r.usage,usageDelta:r.usageDelta},s);return}if(l!==void 0&&(r.action===`park`||r.action===`dispatch-workflow-tasks`)){await a.adopt(r);let e=await dispatchCoordinationStep({action:r.action,callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),workflowToolRunOwner:o.owner,parentWritable:a.parentWritable,serializedContext:a.serializedContext,sessionState:a.sessionState}),t=e.results.length===0?void 0:Date.now();await a.adopt(e),await acknowledgeDelegatedTasksStep({tasks:e.pendingTasks});let i=await waitForRuntimeActionResults({bufferedDeliveries:s,cancellation:u,cursor:a,inboxToken:n.token,initialAcceptedAtMs:t,initialResults:e.results,nextDeliveryRequestId,readers:d,pendingCallIds:l});if(i===`cancelled`){c=void 0;continue}if(i===`cancel-turn`){await finishCancelledTurn({bufferedDeliveries:s,cancellation:u,cursor:a});return}c={kind:`runtime-action-result`,...i};continue}if(r.action===`park`){if(!(r.hasPendingAuthorization||r.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);await u?.dispose(),await a.finish(r,{authorizationAttemptIds:r.authorizationAttemptIds,authorizationNames:r.authorizationNames,kind:`park`,settled:r.settled},s);return}await a.adopt(r),c=void 0}}catch(e){throw await a.send({error:normalizeSerializableError(e),kind:`turn-error`}),e}finally{u!==void 0&&await u.dispose(),l&&await disposeHook(n)}}async function finishCancelledTurn(e){(e.cancellation?.signal.aborted===!0?await e.cancellation.payload:void 0)?.tasks===!0&&await cancelAllIndexedSessionTasksStep({serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState}),await cancelDescendantTurnsStep({serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState}),await e.cancellation?.dispose(),await e.cursor.finish({sessionState:e.cursor.sessionState},{cancelled:!0,kind:`park`},e.bufferedDeliveries)}async function waitForRuntimeActionResults(e){let t,n=[...e.initialResults],r=new Map;if(e.initialAcceptedAtMs!==void 0)for(let t of e.initialResults)r.set(t.callId,e.initialAcceptedAtMs);for(;;){let i=resolveRuntimeActionResultsForCallIds({pendingCallIds:e.pendingCallIds,results:n});if(i!==void 0)return t!==void 0&&await e.cursor.send({kind:`turn-delivery-cancelled`,requestId:t}),{acceptedAtMsByCallId:Object.fromEntries(i.map(e=>[e.callId,r.get(e.callId)])),results:i};e.cursor.sessionState.hasProxyInputRequests&&t===void 0&&(t=e.nextDeliveryRequestId(),await e.cursor.send({continuationToken:e.cursor.sessionState.continuationToken,inboxToken:e.inboxToken,kind:`turn-delivery-request`,requestId:t}));let a=await raceChannelReads(e.readers,e.cancellation?.requested);if(a===`cancel`)return t!==void 0&&await e.cursor.send({kind:`turn-delivery-cancelled`,requestId:t}),`cancelled`;if(a.next.done)throw Error(`Turn inbox closed before runtime actions completed.`);if(a.channel===`workflow`){let t=await handleWorkflowToolRunMessage({callbackMetadataUrl:getWorkflowMetadata().url,cursor:e.cursor,message:a.next.value});t!==void 0&&(n.push(t),r.set(t.callId,Date.now()));continue}let o=a.next.value;if(o.kind===`runtime-action-result`){let t=e.cursor.sessionState.snapshot?.session.state,i=o.results.filter(e=>e.kind===`tool-result`?isInboxToolResultFromRecordedWorkflowToolRun(t,e):e.origin===`child`&&isInboxSubagentResultFromRunningHandle(t,e)||isInboxSubagentResultFromRecordedWorkflowToolRun(t,e));if(i.length>0){let e=Date.now();n.push(...i);for(let t of i)r.set(t.callId,e)}continue}if(o.kind===`subagent-input-request`||o.kind===`subagent-authorization-event`){let t=findRunningAgentHandle(e.cursor.sessionState.snapshot?.session.state,{callId:o.callId});if(t?.identity.name!==o.subagentName||t.address.sessionId!==o.childSessionId)continue;let n=await runProxySubagentEventStep({hookPayload:o,parentWritable:e.cursor.parentWritable,serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState});await e.cursor.adopt(n);continue}if(o.kind===`driver-delivery`&&o.requestId===t){await e.cursor.send({kind:`turn-delivery-accepted`,requestId:o.requestId}),t=void 0;let n=await routeDeliverToChildren({delivery:o.delivery,parentWritable:e.cursor.parentWritable,serializedContext:e.cursor.serializedContext,sessionState:e.cursor.sessionState});if(await e.cursor.adopt({serializedContext:n.serializedContext??e.cursor.serializedContext,sessionState:n.sessionState??e.cursor.sessionState}),n.kind===`cancel-turn`)return n.kind;n.remainder!==void 0&&e.bufferedDeliveries.push(n.remainder)}}}async function runLegacyTurnWorkflow(e){let t=e.stepInput;try{for(;;){let n=await turnStep(t);if(n.action===`done`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`done`,output:n.output??``,isError:n.isError,serializedContext:n.serializedContext,sessionState:n.sessionState,usage:n.usage,usageDelta:n.usageDelta},kind:`turn-result`}});return}if(n.action===`dispatch-workflow-tasks`){await sendTurnControlStep({controlToken:e.completionToken,payload:{action:{kind:`dispatch-workflow-tasks`,pendingCallIds:n.pendingTaskCallIds,serializedContext:n.serializedContext,sessionState:n.sessionState},kind:`turn-result`}});return}if(n.action===`park`){let t=n.pendingCoordinationCallIds;if(!(t!==void 0||n.hasPendingAuthorization||n.hasPendingInputBatch&&e.capabilities?.requestInput===!0||e.mode===`conversation`))throw Error(TASK_MODE_WAIT_ERROR_MESSAGE);let r=t===void 0?{kind:`park`,serializedContext:n.serializedContext,sessionState:n.sessionState,authorizationAttemptIds:n.authorizationAttemptIds,authorizationNames:n.authorizationNames,settled:n.settled}:{kind:`dispatch-coordination`,pendingCallIds:t,serializedContext:n.serializedContext,sessionState:n.sessionState};await sendTurnControlStep({controlToken:e.completionToken,payload:{action:r,kind:`turn-result`}});return}t={input:void 0,parentWritable:t.parentWritable,serializedContext:n.serializedContext,sessionState:n.sessionState}}}catch(t){throw await sendTurnControlStep({controlToken:e.completionToken,payload:{error:normalizeSerializableError(t),kind:`turn-error`}}),t}}turnWorkflow.workflowId=`workflow//eve//turnWorkflow`;export{runTurnOwnedWorkflow,turnWorkflow};