UNPKG

eve

Version:

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

1 lines • 5.38 kB
import{parseWithNitroRolldownAst}from"#internal/bundler/nitro-rolldown.js";import{mayContainWorkflowDirective,readWorkflowDirective}from"#internal/workflow-bundle/workflow-directive-ast.js";const HOISTED_EXECUTE_NAME=`execute`;async function prepareAuthoredWorkflowDirectives(e){if(!mayContainWorkflowDirective(e.source)&&!e.source.includes(`eve/workflow`))return{hasDirectives:!1,hasWorkflowDirective:!1,source:e.source};let t=/\.[cm]?js$/.test(e.filePath)?`${e.filePath}.jsx`:e.filePath,n=await parseWithNitroRolldownAst(t,e.source),r=n.body??[];if(r.some(e=>e.source?.value===`eve/workflow`))throw Error(`${e.filePath}: "eve/workflow" has been removed. Use defineWorkflowTool() from "eve/tools" and call ctx.agent(target, input) or ctx.ask(request) in its executor.`);for(let t of r){if(typeof t.directive!=`string`)break;let n=readWorkflowDirective(t);if(n!==void 0)throw Error(`${JSON.stringify(n)} in "${e.filePath}" is a module-level directive. Put it as the first statement of the function it marks: a top-level "async function" declaration or the "execute" method of a default-exported defineWorkflowTool().`)}let i=new Set;for(let e of r){let t=e.type===`FunctionDeclaration`?e:e.type===`ExportNamedDeclaration`&&e.declaration?.type===`FunctionDeclaration`?e.declaration:void 0;t!==void 0&&i.add(t)}let a=findDefaultExportExecuteProperty(r),o=a!==void 0&&isAstNode(a.value)&&isFunctionLike(a.value)?a.value:void 0;o!==void 0&&i.add(o);let s=collectDirectiveFunctions(n);if(s.length===0)return{hasDirectives:!1,hasWorkflowDirective:!1,source:e.source};let c=s.some(e=>e.directive===`use workflow`);for(let t of s){if(!i.has(t.fn))throw Error(`${JSON.stringify(t.directive)} in "${e.filePath}" marks ${describeFunction(t.fn)}. Workflow directives must mark a top-level "async function" declaration or the "execute" method of a default-exported defineWorkflowTool().`);if(t.fn.async!==!0)throw Error(`${JSON.stringify(t.directive)} in "${e.filePath}" marks ${describeFunction(t.fn)}, which is not async. Declare it with "async function".`);if(t.fn===o&&t.directive!==`use workflow`)throw Error(`"use step" in "${e.filePath}" marks the default export's "execute" method. A tool's "execute" can be a workflow ("use workflow"); steps are the helper functions it calls.`)}let l=s.find(e=>e.fn===o);if(l===void 0||a===void 0)return{hasDirectives:!0,hasWorkflowDirective:c,source:e.source};if(declaresTopLevelBinding(r,HOISTED_EXECUTE_NAME))throw Error(`"use workflow" in "${e.filePath}" marks the "execute" method, but the module also declares a top-level "${HOISTED_EXECUTE_NAME}" binding. eve hoists that method to a top-level "async function ${HOISTED_EXECUTE_NAME}"; rename the existing binding.`);return{hasDirectives:!0,hasWorkflowDirective:c,source:hoistExecuteMethod(e.source,a,l.fn)}}function findDefaultExportExecuteProperty(e){let t=e.find(e=>e.type===`ExportDefaultDeclaration`)?.declaration,n=t?.type===`CallExpression`?t.arguments?.[0]:t;if(n?.type===`ObjectExpression`)return n.properties?.find(e=>e.type===`Property`&&e.kind===`init`&&e.computed!==!0&&readPropertyName(e.key)===HOISTED_EXECUTE_NAME)}function hoistExecuteMethod(e,t,n){if(t.start===void 0||t.end===void 0||!isAstNode(n.body)||n.body.start===void 0||n.body.end===void 0)throw Error(`Cannot hoist an execute method without source ranges.`);let r=n.params??[],i=r[0],a=r[r.length-1],o=i?.start===void 0||a?.end===void 0?``:e.slice(i.start,a.end),s=sliceNode(e,n.typeParameters),c=sliceNode(e,n.returnType),l=e.slice(n.body.start,n.body.end),u=`async function${n.generator===!0?`*`:``} ${HOISTED_EXECUTE_NAME}${s}(${o})${c} ${l}`;return`${e.slice(0,t.start)}${HOISTED_EXECUTE_NAME}${e.slice(t.end)}\n${u}\n`}function sliceNode(e,t){return t==null||t.start===void 0||t.end===void 0?``:e.slice(t.start,t.end)}function declaresTopLevelBinding(e,t){for(let n of e){let e=n.type===`ExportNamedDeclaration`?n.declaration:n;if(e!=null){if((e.type===`FunctionDeclaration`||e.type===`ClassDeclaration`)&&e.id?.name===t)return!0;if(e.type===`VariableDeclaration`){for(let n of e.declarations??[])if(n.id?.name===t)return!0}if(e.type===`ImportDeclaration`){for(let n of e.specifiers??[])if(n.local?.name===t)return!0}}}return!1}function collectDirectiveFunctions(e){let t=[];return visit(e,e=>{if(!isFunctionLike(e))return;let n=readLeadingDirective(e);n!==void 0&&t.push({directive:n,fn:e})}),t}function readLeadingDirective(e){if(isAstNode(e.body)&&e.body.type===`BlockStatement`&&Array.isArray(e.body.body))return readWorkflowDirective(e.body.body[0])}function describeFunction(e){return e.type===`FunctionDeclaration`?e.id?.name===void 0?`a nested function declaration`:`the nested function "${e.id.name}"`:e.type===`ArrowFunctionExpression`?`an arrow function`:e.id?.name===void 0?`a function expression`:`the function "${e.id.name}"`}function readPropertyName(e){if(e!=null){if(e.type===`Identifier`)return e.name;if(e.type===`Literal`&&typeof e.value==`string`)return e.value}}function isFunctionLike(e){return e.type===`FunctionDeclaration`||e.type===`FunctionExpression`||e.type===`ArrowFunctionExpression`}function visit(e,t){if(!e.type?.startsWith(`TS`)){t(e);for(let n of Object.values(e))if(Array.isArray(n))for(let e of n)isAstNode(e)&&visit(e,t);else isAstNode(n)&&visit(n,t)}}function isAstNode(e){return typeof e==`object`&&!!e&&typeof e.type==`string`}export{prepareAuthoredWorkflowDirectives};