eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 6.06 kB
JavaScript
import{createLogger}from"#internal/logging.js";import{getWritable}from"#compiled/@workflow/core/index.js";import{resumeSessionInbox}from"#execution/wire/session-inbox-resume.js";import{resumeWorkflowToolRunAnswers}from"#execution/tools/workflow/answer.js";import{submitActivity}from"#execution/submit-activity.js";import{isTaskWorkflowTargetGone}from"#execution/tasks/workflow-target.js";import{TASK_PROGRESS_STREAM_NAMESPACE,TASK_VIEW_STREAM_NAMESPACE,isTerminalTaskStatus,taskAuthorizationRequestId}from"#tasks/types.js";const log=createLogger(`execution.tasks.run`);async function appendTaskViewStep(e){"use step";let t=getWritable({namespace:TASK_VIEW_STREAM_NAMESPACE}).getWriter();try{await t.write(e.view)}finally{t.releaseLock()}let n=projectTaskActivity({activityObserver:e.activityObserver,settledAt:new Date().toISOString(),view:e.view});submitActivity({events:n,sink:e.activityObserver?.sink})}function projectTaskActivity(e){let t=e.activityObserver?.workIdentity;if(t===void 0)return[];let n=e.view.status;return n===`working`?[{eventId:`${t.id}:started`,kind:`work.started`,startedAt:e.settledAt,work:t}]:n!==`completed`&&n!==`failed`&&n!==`cancelled`?[]:[{eventId:`${t.id}:settled:${n}`,kind:`work.settled`,outcome:n,settledAt:e.settledAt,workId:t.id}]}async function appendTaskProgressStep(e){"use step";let t=getWritable({namespace:TASK_PROGRESS_STREAM_NAMESPACE}).getWriter();try{await t.write(e.progress)}finally{t.releaseLock()}}async function wakeTaskParentStep(e){"use step";let t={message:formatTaskNotification(e.view)};isTerminalTaskStatus(e.view.status)&&(t.task={views:[e.view]});let n={kind:`send`,payload:t,taskDeliveryId:`${e.view.taskId}:ready:${e.view.status}`};try{await resumeSessionInbox(e.token,n)}catch(t){if(isTaskWorkflowTargetGone(t)){log.warn(`task wake target is gone; the parent session already ended`,{status:e.view.status,taskId:e.view.taskId});return}throw t}}async function wakeTaskUpdateParentStep(e){"use step";let t={kind:`send`,payload:{message:`Background task ${e.view.taskId} (${e.view.metadata.name}) update: ${e.update.message}`},taskDeliveryId:`${e.view.taskId}:update:${e.update.updateEpoch}:${e.update.updateIndex}:${e.update.callId}`};try{await resumeSessionInbox(e.token,t)}catch(e){if(isTaskWorkflowTargetGone(e))return;throw e}}async function wakeTaskMessageParentStep(e){"use step";let t={kind:`send`,payload:{message:e.message.message},taskDeliveryId:`${e.taskId}:message:${e.message.messageEpoch}:${e.message.messageIndex}:${e.message.callId}`};try{await resumeSessionInbox(e.token,t)}catch(e){if(isTaskWorkflowTargetGone(e))return;throw e}}async function wakeTaskAgentRequestParentStep(e){"use step";let t=e.request.request;if(t.kind!==`agent-invoke`&&t.kind!==`agent-settled`)throw Error(`Cannot forward task input as an agent request.`);let n={replyTo:e.request.replyTo,request:t,taskId:e.taskId},r=t.kind===`agent-invoke`?t.invocationId:`${t.result.callId}:settled`,i={kind:`send`,payload:{task:{agentRequests:[n]}},taskDeliveryId:`${e.taskId}:agent:${e.request.from.runId}:${r}`};try{await resumeSessionInbox(e.token,i)}catch(e){if(!isTaskWorkflowTargetGone(e))throw e}}async function wakeTaskAuthorizationParentStep(e){"use step";let{event:t}=e.request,n=t.event.data,r={task:{authorizationEvents:[{hookPayload:t,taskId:e.taskId}]}};t.event.type===`authorization.required`&&(r.message=`Background task ${e.taskId} needs authorization.`);let i={kind:`send`,payload:r,taskDeliveryId:`${e.taskId}:authorization:${t.event.type}:${n.turnId}:${n.stepIndex}:${n.sequence}:${taskAuthorizationRequestId(t.event)}`};try{await resumeSessionInbox(e.token,i)}catch(e){if(!isTaskWorkflowTargetGone(e))throw e}}async function wakeWorkflowTaskInputRequestParentStep(e){"use step";let t={kind:`send`,payload:{task:{inputRequests:[e.request.requests===void 0?{replyTo:e.request.replyTo,request:e.request.request,sequence:e.request.sequence,stepIndex:e.request.stepIndex,taskId:e.taskId,turnId:e.request.turnId}:{replyTo:e.request.replyTo,requests:e.request.requests,sequence:e.request.sequence,stepIndex:e.request.stepIndex,taskId:e.taskId,turnId:e.request.turnId}]}},taskDeliveryId:`${e.taskId}:input:${e.request.turnId}:${e.request.stepIndex}:${e.request.sequence}`};try{await resumeSessionInbox(e.token,t)}catch(e){if(!isTaskWorkflowTargetGone(e))throw e}}async function deliverTaskInputResponsesStep(e){"use step";let t=new Set(e.requestIds),n={auth:e.answer.auth,kind:`send`,payload:{inputResponses:e.answer.inputResponses.filter(e=>t.has(e.requestId))},taskDeliveryId:`${e.answer.taskId}:${[...e.requestIds].sort().join(`,`)}`};try{if(e.answer.childResponseUrl!==void 0){let t=await fetch(e.answer.childResponseUrl,{body:JSON.stringify({inputResponses:n.payload.inputResponses}),headers:{"content-type":`application/json`},method:`POST`,redirect:`error`});if(t.status===404)return`unreachable`;if(!t.ok)throw Error(`Remote task input delivery failed with HTTP ${t.status}.`)}else e.answerHook===void 0?await resumeSessionInbox(e.answer.childSessionInbox??e.answer.childContinuationToken,n):await resumeWorkflowToolRunAnswers(e.answer.childContinuationToken,n.payload.inputResponses);return`delivered`}catch(t){if(isTaskWorkflowTargetGone(t))return log.warn(`task input answer target is gone; the child turn already ended`,{taskId:e.answer.taskId}),`unreachable`;throw t}}function formatTaskNotification(e){let t=`Background task ${e.taskId} (${e.metadata.name})`;return e.status===`input_required`?`${t} needs input.`:e.status===`completed`?`${t} is completed.\n\nResult:\n${formatTaskOutput(e.lastOutput.data)}`:e.status===`failed`?`${t} failed.\n\nError:\n${formatTaskOutput(e.lastOutput.data)}`:`${t} is cancelled.`}function formatTaskOutput(e){return typeof e==`string`?e:JSON.stringify(e)??`null`}export{appendTaskProgressStep,appendTaskViewStep,deliverTaskInputResponsesStep,formatTaskNotification,projectTaskActivity,wakeTaskAgentRequestParentStep,wakeTaskAuthorizationParentStep,wakeTaskMessageParentStep,wakeTaskParentStep,wakeTaskUpdateParentStep,wakeWorkflowTaskInputRequestParentStep};