eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 5.51 kB
JavaScript
import{createLogger}from"#internal/logging.js";import{SessionDynamicSubagentSelectionsKey,TurnDynamicSubagentSelectionsKey}from"#context/keys.js";import{BundleKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{deserializeContext}from"#context/serialize.js";import{readDurableSession}from"#execution/durable-session-store.js";import{findBackgroundWorkflowToolRun}from"#harness/workflow-tool-runs.js";import{getAgentHandleStore}from"#subagents/handles/store.js";import{getDynamicSubagentSelection}from"#context/dynamic-subagent-lifecycle.js";import{activeTurnId}from"#harness/active-turn-id.js";import{prepareActionDispatch}from"#execution/coordination-dispatch-shared.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{AGENT_TOOL_DESCRIPTION,AGENT_TOOL_NAME}from"#tools/framework/agent-contract.js";import{isAgentHandleAction}from"#subagents/handle-dispatch.js";import{createRecursiveAgentRootOnlyResult,createUnavailableDynamicSubagentResult,getSubagentName}from"#execution/dispatch-action-failures.js";const log=createLogger(`execution.agent-invocation`);async function prepareOwnerAgentInvocation(e){let t=readDurableSession(e.sessionState),n=await deserializeContext(e.serializedContext),r=getHarnessEmissionState(t.state),i=e.taskId===void 0?void 0:findBackgroundWorkflowToolRun(t.state,e.taskId),a=resolveAgentInvocationAction({ctx:n,input:e.invocation,invocationId:e.invocationId});return await prepareActionDispatch({batch:{requests:[a],event:{...r,stepIndex:i?.origin.stepIndex??r.stepIndex,turnId:i?.origin.turnId??activeTurnId(r)}},ctx:n,durableSession:t,fanoutSize:1,plan:({bundle:t,ctx:n,session:r})=>[planAgentDispatch({action:a,bundle:t,ctx:n,knownAgentIds:e.knownAgentIds,session:r})],planReusesOwnerSandbox:({bundle:e,plan:t})=>ownerPlanReusesSandbox({bundle:e,plan:t}),serializedContext:e.serializedContext})}function planAgentDispatch(e){let t=new Set(e.knownAgentIds??(getAgentHandleStore(e.session.state)?.handles??[]).map(e=>e.identity.id)),n=e.action.input.agentId,r=typeof n==`string`&&n.trim()!==``?n:void 0;if(r!==void 0&&isAgentHandleAction(e.action)){if(t.has(r)){let t=e.bundle.subagentRegistry.dynamicNodeIds?.has(e.action.nodeId)===!0?getDynamicSubagentSelection(e.ctx,e.action.nodeId):void 0;return{action:e.action,agentId:r,dynamicRemoteAgent:e.action.kind===`remote-agent-call`&&t?.kind===`remote`?t.remoteAgent:void 0,kind:`resume`}}log.warn(`unknown agentId on subagent call; starting a new agent`,{agentId:r,callId:e.action.callId})}return classifyFreshStart(e)}function classifyFreshStart(e){let{action:t}=e,n=e.bundle.subagentRegistry.subagentsByNodeId,r=e.bundle.subagentRegistry.dynamicNodeIds?.has(t.nodeId)===!0,i=r?getDynamicSubagentSelection(e.ctx,t.nodeId):void 0;if(r&&(i===void 0||t.kind===`subagent-call`&&i.kind!==`subagent`||t.kind===`remote-agent-call`&&i.kind!==`remote`))return log.warn(`dynamic subagent call blocked after availability changed`,{callId:t.callId,nodeId:t.nodeId,subagentName:getSubagentName(t)}),{kind:`reject`,result:createUnavailableDynamicSubagentResult(t)};if(isRecursiveAgentAction(t,n)&&e.session.rootSessionId!==void 0)return log.warn(`recursive agent call blocked outside the root session`,{callId:t.callId,nodeId:t.nodeId,rootSessionId:e.session.rootSessionId,subagentName:t.subagentName}),{kind:`reject`,result:createRecursiveAgentRootOnlyResult(t)};if(t.kind===`remote-agent-call`)return{kind:`start`,target:{action:t,dynamicRemoteAgent:i?.kind===`remote`?i.remoteAgent:void 0,kind:`remote`}};let a=i?.kind===`subagent`?i.agentConfig:void 0,o=n.get(t.nodeId),s=a?.description??(o?.definition.kind===`subagent`?o.definition.description:void 0);return{kind:`start`,target:{action:t,dynamicSubagentAgentConfig:a,kind:`local`,source:s===void 0?{outputSchema:e.bundle.turnAgent.outputSchema,type:`runtime`}:{description:s,outputSchema:a?.outputSchema??e.bundle.graph?.nodesByNodeId.get(t.nodeId)?.turnAgent?.outputSchema,type:`local`}}}}function ownerPlanReusesSandbox(e){return e.plan.some(t=>{if(t.kind!==`start`||t.target.kind!==`local`)return!1;let n=t.target.action;return n.subagentName===`agent`&&!e.bundle.subagentRegistry.subagentsByNodeId.has(n.nodeId)||e.bundle.graph?.nodesByNodeId.get(n.nodeId)?.sandboxRegistry.sandbox.definition.kind===`parent`})}function isRecursiveAgentAction(e,t){return e.kind===`subagent-call`&&e.subagentName===`agent`&&!t.has(e.nodeId)}function resolveAgentInvocationAction(e){let t=e.ctx.require(BundleKey),n=t.subagentRegistry.subagentsByName.get(e.input.target),r=n===void 0?Object.values({...e.ctx.get(SessionDynamicSubagentSelectionsKey),...e.ctx.get(TurnDynamicSubagentSelectionsKey)}).find(t=>t!==null&&t.prepared?.name===e.input.target):void 0,i=n?.definition??r?.prepared??(e.input.target===AGENT_TOOL_NAME&&t.nodeId===void 0?{description:AGENT_TOOL_DESCRIPTION,kind:`subagent`,name:AGENT_TOOL_NAME,nodeId:ROOT_RUNTIME_AGENT_NODE_ID}:void 0);if(i===void 0)throw Error(`Agent target "${e.input.target}" is not available to this agent.`);let a={message:e.input.message};e.input.agentId!==void 0&&(a.agentId=e.input.agentId),e.input.outputSchema!==void 0&&(a.outputSchema=e.input.outputSchema);let o={callId:e.invocationId,description:i.description??``,input:a,name:i.name,nodeId:i.nodeId};return i.kind===`remote`?{...o,kind:`remote-agent-call`,remoteAgentName:i.name}:{...o,kind:`subagent-call`,subagentName:i.name}}export{planAgentDispatch,prepareOwnerAgentInvocation,resolveAgentInvocationAction};