eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 10.5 kB
JavaScript
import{AuthKey,InitiatorAuthKey,SessionDynamicSubagentSelectionsKey,TurnDynamicSubagentSelectionsKey}from"#context/keys.js";import{createSubagentCalledEvent}from"#protocol/message.js";import{workflowEntryReference}from"#execution/workflow-runtime.js";import{getWorkflowMetadata}from"#compiled/@workflow/core/index.js";import{deriveAgentOperationId}from"#subagents/handles/operation-id.js";import{readDurableSession,replaceDurableSessionSnapshot}from"#execution/durable-session-store.js";import{findBackgroundWorkflowToolRun,readWorkflowTaskView}from"#harness/workflow-tool-runs.js";import{getAgentHandleStore,writeHandles}from"#subagents/handles/store.js";import{projectToDurableSession}from"#execution/session.js";import{AGENT_BUSY,AGENT_MISMATCH,AGENT_UNREACHABLE,formatAgentBusyMessage}from"#subagents/agent-handle-errors.js";import{clearProxyInputRequestsForChild,clearProxyInputRequestsForTask}from"#harness/proxy-input-requests.js";import{accumulateSessionUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{abandonAgentInvocationOwners,applyTaskAgentHandleCommand}from"#subagents/handles/transitions.js";import{createSubagentReceiptIdentity}from"#execution/tools/subagent/receipt-identity.js";import{createAgentErrorResult,dispatchToClaimedAgentAddress}from"#subagents/handle-dispatch.js";import{createAgentContinuationBundle}from"#subagents/continuation-bundle.js";import{startSubagent}from"#execution/tools/subagent/start.js";import{prepareOwnerAgentInvocation}from"#execution/tools/subagent/invoke-preparation.js";import{prepareAgentInvocationTrace}from"#tracing/agent-invocation-coordinator.js";import{flushAgentInvocationTraces,settleAgentInvocationTrace}from"#tracing/agent-invocation-terminal.js";async function dispatchAgentInvocation(e){let t=readDurableSession(e.sessionState),n=getAgentHandleStore(t.state)?.handles??[],r=await prepareOwnerAgentInvocation({invocation:e.request.input,invocationId:e.request.invocationId,knownAgentIds:n.map(e=>e.identity.id),serializedContext:e.invocationContext??e.serializedContext,sessionState:e.sessionState,taskId:e.taskId}),i=r.plan[0];if(i===void 0)throw Error(`Agent invocation produced no executable plan entry.`);if(i.kind===`reject`)return{kind:`failed`,result:i.result,serializedContext:e.serializedContext,sessionState:e.sessionState};let a=i.kind===`start`?i.target.action:i.action,o=prepareAgentInvocationTrace({conversation:r.inheritedConversation,invocation:a,ownerId:e.ownerId,serializedContext:e.serializedContext,sessionId:r.session.sessionId,sessionState:t.state,startTimeMs:Date.now(),taskId:e.taskId,turnId:r.batch.event.turnId}),s=r.activityObserver===void 0||e.activityWorkIdentity===void 0?void 0:{sink:r.activityObserver.sink,workIdentity:e.activityWorkIdentity},c=r.session,currentAgentHandles=()=>getAgentHandleStore(c.state)?.handles??[],sessionState=()=>replaceDurableSessionSnapshot({session:projectToDurableSession(c),state:e.sessionState}),failed=async e=>({kind:`failed`,result:e,serializedContext:await flushAgentInvocationTraces(o.fail(e)),sessionState:sessionState()}),applyHandleCommand=e=>{let t=applyTaskAgentHandleCommand(c,e);return c=t.session,t.result},l,u;if(i.kind===`resume`){let t=currentAgentHandles().filter(t=>t.phase===`claimed`&&t.ownerId===e.ownerId&&t.callId===i.action.callId&&t.identity.id===i.agentId);if(t.length>1)throw Error(`Invocation owner "${e.ownerId}" has multiple claims for "${i.action.callId}".`);let n=t[0];if(n===void 0){let t=deriveAgentOperationId({callId:i.action.callId,parentSessionId:r.session.sessionId,parentTurnId:r.batch.event.turnId}),a=applyHandleCommand({agentId:i.agentId,callId:i.action.callId,expectedTarget:i.action.kind===`remote-agent-call`?`remote`:`local`,invokedName:i.action.kind===`remote-agent-call`?i.action.remoteAgentName:i.action.subagentName,kind:`claim`,operationId:t,ownerId:e.ownerId});if(n=readClaimedHandle(a),n===void 0)return failed(createTaskClaimError(i.action,i.agentId,a))}let a=createAgentContinuationBundle({action:i.action,bundle:r.bundle,dynamicRemoteAgent:i.dynamicRemoteAgent});l=await dispatchToClaimedAgentAddress({activityObserver:s,action:i.action,auth:r.auth,bundle:a,currentSession:c,handle:n,reply:e.taskId===void 0?{kind:`reply`,parentToken:e.replyTo}:{kind:`reply`,parentToken:e.replyTo,taskId:e.taskId}}),l.kind===`error`&&l.deliveryPermanent===!0&&applyHandleCommand({agentId:i.agentId,kind:`remove`,ownerId:e.ownerId}),u=n.identity.id}else{let t=i.target.action,n=currentAgentHandles().filter(n=>n.phase===`reserved`&&n.ownerId===e.ownerId&&n.callId===t.callId&&n.identity.name===t.name&&n.identity.nodeId===t.nodeId),a=n.length===1?{identity:n[0].identity,operation:{id:n[0].operationId}}:createSubagentReceiptIdentity({callId:t.callId,subagentName:t.kind===`remote-agent-call`?t.remoteAgentName:t.subagentName,nodeId:t.nodeId,parentSessionId:r.session.sessionId,parentTurnId:r.batch.event.turnId});if(n.length>1)throw Error(`Invocation owner "${e.ownerId}" has multiple reservations for "${t.callId}".`);if(n.length===0&&applyHandleCommand({identity:a.identity,callId:t.callId,kind:`reserve`,operationId:a.operation.id,ownerId:e.ownerId}).kind!==`ready`)throw Error(`Agent handle store rejected start operation "${a.operation.id}".`);if(l=await startSubagent({auth:r.auth,batchEvent:r.batch.event,bundle:r.bundle,callbackBaseUrl:e.callbackBaseUrl,capabilities:r.capabilities,channelMetadata:r.channelMetadata,inheritedConversation:r.inheritedConversation,currentSession:c,fanoutSize:r.fanoutSize,initiatorAuth:r.initiatorAuth,localDevRequest:r.localDevRequest,parentContinuationToken:e.replyTo,activityObserver:r.activityObserver,taskActivityObserver:s,sandboxSessionId:r.sandboxSessionId,session:c,taskId:e.taskId,target:i.target,trace:o.dispatch}),u=a.identity.id,l.kind===`error`)applyHandleCommand({agentId:u,kind:`remove`,ownerId:e.ownerId});else if(readClaimedHandle(applyHandleCommand({address:l.address,kind:`confirm`,operationId:a.operation.id,ownerId:e.ownerId}))===void 0)throw Error(`Agent handle store could not confirm start operation "${a.operation.id}".`)}if(l.kind===`error`)return failed(l.result);let d=i.kind===`resume`?i.action:i.target.action,f=i.kind===`resume`?i.dynamicRemoteAgent:i.target.kind===`remote`?i.target.dynamicRemoteAgent:void 0,p=createSubagentCalledEvent({agentId:u,callId:l.callId,childSessionId:l.address.sessionId,name:l.name,remote:l.address.kind===`agent/remote`?{resolverId:f===void 0?d.nodeId:f.credentialsStepId,url:l.address.url}:void 0,sequence:r.batch.event.sequence,sessionId:r.session.sessionId,toolName:l.toolName,turnId:r.batch.event.turnId,workflowId:workflowEntryReference.workflowId});return e.emit!==void 0&&await e.emit(p),{kind:`dispatched`,agentId:u,event:p,serializedContext:o.serializedContext,sessionState:sessionState()}}async function dispatchTaskAgentInvocationStep(e){"use step";let t,n;if(e.taskId!==void 0){let r=readDurableSession(e.sessionState),i=findBackgroundWorkflowToolRun(r.state,e.taskId);if(i===void 0||readWorkflowTaskView(i.task)!==void 0)return{kind:`not-admitted`,sessionState:e.sessionState};n=i.task.dispatchContext,i.task.metadata.kind===`subagent`&&(t=i.task.activityWorkIdentity)}return await dispatchAgentInvocation({...e,activityWorkIdentity:t,callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),invocationContext:n===void 0?void 0:applyTaskDispatchContext(e.serializedContext,n)})}function applyTaskDispatchContext(e,t){let n={...e,[AuthKey.name]:t.auth.current,[InitiatorAuthKey.name]:t.auth.initiator};for(let[e,r]of[[SessionDynamicSubagentSelectionsKey.name,t.sessionDynamicSubagentSelections],[TurnDynamicSubagentSelectionsKey.name,t.turnDynamicSubagentSelections]])r===void 0?delete n[e]:n[e]=r;return n}async function settleTaskAgentInvocationStep(e){"use step";let t=readDurableSession(e.sessionState),n=getAgentHandleStore(t.state)?.handles??[],r=n.find(t=>t.phase===`claimed`&&t.ownerId===e.ownerId&&t.callId===e.result.callId);if(r?.phase!==`claimed`)return{settled:!1,serializedContext:e.serializedContext,sessionState:e.sessionState};let i=await flushAgentInvocationTraces(settleAgentInvocationTrace({acceptedAtMs:Date.now(),result:e.result,serializedContext:e.serializedContext,sessionId:t.sessionId})),a=e.result.outcome.kind===`terminal`?n.filter(e=>e!==r):n.map(t=>t===r?e.result.outcome.result.kind===`cancelled`?{address:r.address,identity:r.identity,lastStatus:`(cancelled)`,phase:`parked`}:{address:r.address,identity:r.identity,phase:`available`}:t),o=writeHandles(t,a);e.result.outcome.kind===`terminal`&&(o=e.taskId===void 0?`continuationToken`in r.address?clearProxyInputRequestsForChild(o,r.address.continuationToken):o:clearProxyInputRequestsForTask(o,e.taskId)),o=setTurnUsageState(o,accumulateSessionUsage({previous:getTurnUsageState(o.state),usage:e.result.outcome.usageDelta}));let s=e.taskId===void 0?void 0:findBackgroundWorkflowToolRun(o.state,e.taskId),c=s?.task.metadata.kind===`subagent`&&s.callId===e.result.callId;return{settled:!0,completion:e.result.outcome.result.kind!==`succeeded`||c?void 0:{type:`subagent.completed`,data:{callId:e.result.callId,subagentName:e.result.subagentName,output:typeof e.result.output==`string`?e.result.output:JSON.stringify(e.result.output)}},serializedContext:i,sessionState:replaceDurableSessionSnapshot({session:o,state:e.sessionState})}}async function releaseAgentInvocationOwnerStep(e){"use step";let t=readDurableSession(e.sessionState),n=e.cancelled?abandonAgentInvocationOwners(t,new Set([e.ownerId])):applyTaskAgentHandleCommand(t,{kind:`release-owner`,ownerId:e.ownerId}).session;return{sessionState:n===t?e.sessionState:replaceDurableSessionSnapshot({session:n,state:e.sessionState})}}function readClaimedHandle(e){let t=e.kind===`ready`?e.handle:void 0;return t?.phase===`claimed`?t:void 0}function createTaskClaimError(e,t,n){return n.kind===`mismatch`?createAgentErrorResult({action:e,code:AGENT_MISMATCH,message:`Agent "${t}" no longer matches this subagent definition. Start a new agent instead.`}):n.kind===`busy`?createAgentErrorResult({action:e,code:AGENT_BUSY,message:formatAgentBusyMessage({agentId:t,agentName:n.handle.identity.name,ownerId:`ownerId`in n.handle?n.handle.ownerId:void 0})}):createAgentErrorResult({action:e,code:AGENT_UNREACHABLE,message:`Agent with id "${t}" is no longer reachable.`})}export{dispatchAgentInvocation,dispatchTaskAgentInvocationStep,releaseAgentInvocationOwnerStep,settleTaskAgentInvocationStep};