UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

1 lines 5.45 kB
import{parseJsonObject}from"#shared/json.js";import{coalesceTurnInputs}from"#harness/messages.js";const PENDING_INPUT_BATCH_KEY=`eve.runtime.pendingInputBatch`,APPROVED_TOOLS_KEY=`eve.runtime.hitl.approvedTools`,DEFERRED_STEP_INPUT_KEY=`eve.runtime.deferredStepInput`;function hasStepInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}function consumeDeferredStepInput(e){let n=getDeferredStepInput(e.session);if(n===void 0)return e;let r=clearDeferredStepInput(e.session);return e.input===void 0?{input:n,session:r}:{input:coalesceTurnInputs(n,e.input),session:r}}function hasDeferredStepInput(e){return getDeferredStepInput(e)!==void 0}function resolvePendingInput(e){let{stepInput:t}=e,n=e.session,r=[...e.history??n.history],i=getPendingInputBatch(n.state);if(i===void 0)return{outcome:`continue`,messages:r,session:n};let a=t?.inputResponses??[];if(a.length===0&&t?.message===void 0)return{outcome:`unresolved`,messages:r,session:n};if(a.length===0&&t?.message!==void 0){let e=buildToolResponseParts(i,[]),a=[...r,...i.responseMessages];e.length>0&&a.push({content:e,role:`tool`});let o=buildRejectedActionBatch(i,[]);return n=clearPendingInputBatch(n),i.requests.some(e=>isApprovalRequest(e))?(n=queueDeferredStepInput(n,{message:t.message}),{deferredMessage:!0,outcome:`resolved`,messages:a,rejectedActions:o,session:n}):{outcome:`resolved`,messages:a,rejectedActions:o,session:n}}n=recordApprovedTools({pendingBatch:i,resolveApprovalKey:e.resolveApprovalKey,responses:a,session:n});let o=buildToolResponseParts(i,a),s=[...r,...i.responseMessages];o.length>0&&s.push({content:o,role:`tool`});let c=buildRejectedActionBatch(i,a);return n=clearPendingInputBatch(n),t?.message!==void 0&&i.requests.some(e=>isApprovalRequest(e))?(n=queueDeferredStepInput(n,{message:t.message}),{deferredMessage:!0,outcome:`resolved`,messages:s,rejectedActions:c,session:n}):{outcome:`resolved`,messages:s,rejectedActions:c,session:n}}function hasPendingInputBatch(e){return getPendingInputBatch(e)!==void 0}function getPendingInputBatch(e){let t=e?.[PENDING_INPUT_BATCH_KEY];if(typeof t!=`object`||!t)return;let r=t;if(!(!Array.isArray(r.requests)||!Array.isArray(r.responseMessages)))return r}function setPendingInputBatch(e){let t={...e.session.state};return t[PENDING_INPUT_BATCH_KEY]={event:e.event,requests:[...e.requests],responseMessages:[...e.responseMessages]},{...e.session,state:t}}function clearPendingInputBatch(e){if(e.state?.[PENDING_INPUT_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_INPUT_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getDeferredStepInput(e){return e.state?.[DEFERRED_STEP_INPUT_KEY]}function queueDeferredStepInput(e,n){let r=getDeferredStepInput(e),a=r===void 0?n:coalesceTurnInputs(r,n),o={...e.state};return o[DEFERRED_STEP_INPUT_KEY]=a,{...e,state:o}}function clearDeferredStepInput(e){if(e.state?.[DEFERRED_STEP_INPUT_KEY]===void 0)return e;let t={...e.state};return delete t[DEFERRED_STEP_INPUT_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getApprovedTools(e){let t=e.state?.[APPROVED_TOOLS_KEY];return Array.isArray(t)?new Set(t):new Set}function recordApprovedTools(e){let t=new Set(e.responses.filter(e=>e.optionId===`approve`).map(e=>e.requestId)),n=e.pendingBatch.requests.filter(e=>t.has(e.requestId)).map(t=>e.resolveApprovalKey?.(t)??t.action.toolName);if(n.length===0)return e.session;let i=getApprovedTools(e.session),a=[...new Set([...i,...n])],o={...e.session.state};return o[APPROVED_TOOLS_KEY]=a,{...e.session,state:o}}function resolveApprovalOutcome(e){return{approved:e?.optionId===`approve`,reason:e===void 0?`Ignored because the user continued without responding.`:void 0}}function buildRejectedActionBatch(e,t){if(e.event===void 0)return;let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests){if(!isApprovalRequest(t))continue;let{approved:e,reason:i}=resolveApprovalOutcome(n.get(t.requestId));e||r.push({callId:t.action.callId,isError:!0,kind:`tool-result`,output:{code:`TOOL_EXECUTION_DENIED`,message:i??`Tool execution was denied.`},toolName:t.action.toolName})}return r.length>0?{event:e.event,results:r}:void 0}function buildToolResponseParts(e,t){let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests)r.push(...buildToolResponsePartsForRequest(t,n.get(t.requestId)));return r}function buildToolResponsePartsForRequest(e,t){if(isApprovalRequest(e)){let{approved:n,reason:r}=resolveApprovalOutcome(t),i=[{approvalId:e.requestId,approved:n,reason:r,type:`tool-approval-response`}];return n||i.push({output:{type:`execution-denied`,reason:r},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}),i}return[{output:{type:`json`,value:t===void 0?{status:`ignored`}:{optionId:t.optionId,text:t.text,status:`answered`}},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}]}function isApprovalRequest(e){return e.options?.length===2&&e.options[0]?.id===`approve`&&e.options[1]?.id===`deny`}function createRuntimeToolCallActionFromToolCall(e){return{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input),kind:`tool-call`,toolName:e.toolCall.toolName}}function resolveToolCallInputObject(t){return t==null?{}:parseJsonObject(t)}export{consumeDeferredStepInput,createRuntimeToolCallActionFromToolCall,getApprovedTools,hasDeferredStepInput,hasPendingInputBatch,hasStepInput,resolvePendingInput,setPendingInputBatch};