eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 8.51 kB
JavaScript
import{createAuthorizationCompletedPart,createAuthorizationRequiredPart}from"#client/authorization-message-parts.js";import{approvedApproval,createToolMetadata,mergeToolMetadata,normalizeActionRequest,normalizeActionResult,stringifyUnknown,toMessageInputRequest}from"#client/message-action-parts.js";function defaultMessageReducer(){return{initial(){return{messages:[]}},reduce(e,t){return reduceMessageData(e,t)}}}function reduceMessageData(e,s){switch(s.type){case`client.message.submitted`:return upsertMessage(e,{id:optimisticUserMessageId(s.data.submissionId),metadata:{optimistic:!0,status:`submitted`},parts:[{type:`text`,text:s.data.message}],role:`user`});case`client.message.failed`:return upsertMessage(e,{id:optimisticUserMessageId(s.data.submissionId),metadata:{optimistic:!0,status:`failed`},parts:[{type:`text`,text:s.data.message}],role:`user`});case`client.input.responded`:{let t=e;for(let e of s.data.responses)t=respondToInputRequest(t,e);return t}case`message.received`:return upsertMessage(e,{id:`${s.data.turnId}:user`,metadata:{status:`complete`,turnId:s.data.turnId},parts:projectReceivedParts(s.data.parts,s.data.message),role:`user`});case`step.started`:return updateAssistantMessage(e,s.data.turnId,e=>ensureStepStartPart(e,s.data.stepIndex));case`reasoning.appended`:return updateAssistantMessage(e,s.data.turnId,e=>upsertRun(ensureStepStartPart(e,s.data.stepIndex),{state:`streaming`,stepIndex:s.data.stepIndex,text:s.data.reasoningSoFar,type:`reasoning`}));case`reasoning.completed`:return updateAssistantMessage(e,s.data.turnId,e=>upsertRun(ensureStepStartPart(e,s.data.stepIndex),{state:`done`,stepIndex:s.data.stepIndex,text:s.data.reasoning,type:`reasoning`}));case`actions.requested`:{let t=e;for(let e of s.data.actions){let n=normalizeActionRequest(e);t=updateAssistantMessage(t,s.data.turnId,t=>upsertPart(ensureStepStartPart(t,s.data.stepIndex),{input:`input`in e?e.input:void 0,state:`input-available`,stepIndex:s.data.stepIndex,toolCallId:e.callId,toolMetadata:createToolMetadata(n),toolName:n.toolName,type:`dynamic-tool`}))}return t}case`input.requested`:{let t=e;for(let e of s.data.requests){let n=normalizeActionRequest(e.action);t=updateAssistantMessage(t,s.data.turnId,t=>upsertPart(ensureStepStartPart(t,s.data.stepIndex),{approval:{id:e.requestId},input:e.action.input,state:`approval-requested`,stepIndex:s.data.stepIndex,toolCallId:e.action.callId,toolMetadata:createToolMetadata(n,{inputRequest:toMessageInputRequest(e)}),toolName:n.toolName,type:`dynamic-tool`}))}return t}case`action.result`:{let t=normalizeActionResult(s.data.result),a=findToolPart(e,s.data.result.callId),o=s.data.error?.code===`TOOL_EXECUTION_DENIED`,c=s.data.status===`failed`&&!o,l=a?.approval?.id??s.data.result.callId,u=mergeToolMetadata(a?.toolMetadata,createToolMetadata(t)),d={input:a?.input,stepIndex:s.data.stepIndex,toolCallId:s.data.result.callId,toolMetadata:u,toolName:a?.toolName??t.toolName,type:`dynamic-tool`},f;return f=o?{...d,approval:{approved:!1,id:l,reason:s.data.error?.message},state:`output-denied`}:c?{...d,approval:approvedApproval(a),errorText:s.data.error?.message??stringifyUnknown(s.data.result.output),state:`output-error`}:{...d,approval:approvedApproval(a),output:s.data.result.output,state:`output-available`},a===void 0?updateAssistantMessage(e,s.data.turnId,e=>upsertPart(ensureStepStartPart(e,s.data.stepIndex),f)):updateToolPart(e,s.data.result.callId,f)}case`authorization.required`:return updateAssistantMessage(e,s.data.turnId,e=>upsertPart(ensureStepStartPart(e,s.data.stepIndex),createAuthorizationRequiredPart(s)));case`authorization.completed`:return completeAuthorization(e,s);case`message.appended`:return updateAssistantMessage(e,s.data.turnId,e=>upsertRun(ensureStepStartPart(e,s.data.stepIndex),{state:`streaming`,stepIndex:s.data.stepIndex,text:s.data.messageSoFar,type:`text`}));case`message.completed`:return updateAssistantMessage(e,s.data.turnId,e=>s.data.message===null?removeTextPart(e,s.data.stepIndex):upsertRun(ensureStepStartPart(e,s.data.stepIndex),{state:`done`,stepIndex:s.data.stepIndex,text:s.data.message,type:`text`}));case`result.completed`:return updateAssistantMetadata(e,s.data.turnId,{result:s.data.result});case`turn.completed`:return updateAssistantMetadata(e,s.data.turnId,{status:`complete`});case`turn.cancelled`:return updateAssistantMessage(e,s.data.turnId,e=>({...e,metadata:{...e.metadata,status:`complete`},parts:e.parts.map(e=>(e.type===`text`||e.type===`reasoning`)&&e.state===`streaming`?{...e,state:`done`}:e)}));case`turn.failed`:case`session.failed`:return e;default:return e}}function respondToInputRequest(e,t){let n=findToolPartByApprovalId(e,t.requestId);if(!n)return e;let r={id:t.requestId};return t.text!==void 0&&(r.reason=t.text),updateToolPart(e,n.toolCallId,{approval:r,input:n.input,state:`approval-responded`,stepIndex:n.stepIndex,toolCallId:n.toolCallId,toolMetadata:mergeToolMetadata(n.toolMetadata,{eve:{inputResponse:t,kind:n.toolMetadata?.eve?.kind??`unknown`,name:n.toolMetadata?.eve?.name??n.toolName}}),toolName:n.toolName,type:`dynamic-tool`})}function updateAssistantMessage(e,t,n){return upsertMessage(e,n(e.messages.find(e=>e.role===`assistant`&&e.metadata?.turnId===t)??createAssistantMessage(t)))}function updateAssistantMetadata(e,t,n){return updateAssistantMessage(e,t,e=>({...e,metadata:{...e.metadata,...n}}))}function createAssistantMessage(e){return{id:`${e}:assistant`,metadata:{status:`streaming`,turnId:e},parts:[],role:`assistant`}}function ensureStepStartPart(e,t){let n=e.parts.filter(e=>e.type===`step-start`).length;if(n>t)return e;let r=t-n+1;return{...e,parts:[...e.parts,...Array.from({length:r},()=>({type:`step-start`}))]}}function upsertPart(e,t){let n=e.parts.findIndex(e=>partKey(e)===partKey(t)),r=n===-1?[...e.parts,t]:[...e.parts.slice(0,n),t,...e.parts.slice(n+1)];return{...e,metadata:{...e.metadata,status:t.type===`text`&&t.state===`done`?`complete`:`streaming`},parts:r}}function upsertRun(e,t){let n=-1;for(let r=e.parts.length-1;r>=0;--r){let i=e.parts[r];if(i?.type===t.type&&i.stepIndex===t.stepIndex){n=r;break}}let r=n!==-1&&e.parts[n].state===`streaming`?[...e.parts.slice(0,n),t,...e.parts.slice(n+1)]:[...e.parts,t];return{...e,metadata:{...e.metadata,status:t.type===`text`&&t.state===`done`?`complete`:`streaming`},parts:r}}function removeTextPart(e,t){let n=e.parts.filter(e=>e.type!==`text`||e.stepIndex!==t);return n.length===e.parts.length?e:{...e,metadata:{...e.metadata,status:`complete`},parts:n}}function updateToolPart(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.parts.some(e=>e.type===`dynamic-tool`&&e.toolCallId===t));return r?upsertMessage(e,upsertPart(r,n)):e}function completeAuthorization(t,n){let r=findLatestPendingAuthorizationPart(t,n.data.name),i=createAuthorizationCompletedPart(n,r);return r===void 0?updateAssistantMessage(t,n.data.turnId,e=>upsertPart(ensureStepStartPart(e,n.data.stepIndex),i)):updateAuthorizationPart(t,r,i)}function updateAuthorizationPart(e,t,n){let r=e.messages.find(e=>e.role===`assistant`&&e.parts.some(e=>e===t));return r?upsertMessage(e,upsertPart(r,n)):e}function findToolPart(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.toolCallId===t)return e}function findLatestPendingAuthorizationPart(e,t){for(let n=e.messages.length-1;n>=0;--n){let r=e.messages[n];if(r?.role===`assistant`)for(let e=r.parts.length-1;e>=0;--e){let n=r.parts[e];if(n?.type===`authorization`&&n.state===`required`&&n.name===t)return n}}}function findToolPartByApprovalId(e,t){for(let n of e.messages)for(let e of n.parts)if(e.type===`dynamic-tool`&&e.approval?.id===t)return e}function projectReceivedParts(e,t){return e?.map(e=>e.type===`text`?{state:`done`,text:e.text,type:`text`}:{filename:e.filename,mediaType:e.mediaType,size:e.size,type:`file`,url:e.url})??[{state:`done`,text:t,type:`text`}]}function partKey(e){switch(e.type){case`text`:return`text:${e.stepIndex??0}`;case`reasoning`:return`reasoning:${e.stepIndex??0}`;case`file`:return`file:${e.stepIndex??0}:${e.filename??e.url??e.mediaType}`;case`step-start`:return`step-start`;case`authorization`:return`authorization:${e.turnId}:${e.stepIndex}:${e.name}`;case`dynamic-tool`:return`dynamic-tool:${e.toolCallId}`}}function upsertMessage(e,t){let n=e.messages.findIndex(e=>e.id===t.id);return n===-1?{messages:[...e.messages,t]}:{messages:[...e.messages.slice(0,n),t,...e.messages.slice(n+1)]}}function optimisticUserMessageId(e){return`optimistic:${e}:user`}export{defaultMessageReducer};