eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
1 lines • 4.45 kB
JavaScript
import{loadContext}from"#context/container.js";import{isObject}from"#shared/guards.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{resolveApprovalPolicy}from"#approval/definition.js";import{tool}from"ai";import{authorizationPendingModelText,isAuthorizationPendingModelOutput,isAuthorizationSignal,modelFacingAuthorizationOutput}from"#harness/authorization.js";import{createBackgroundToolCallBatch,executeBackgroundToolCall}from"#harness/background-tools.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{normalizeToolJsonOutput,normalizeToolModelOutput}from"#harness/tool-model-output.js";import{stashToolInterrupt}from"#harness/tool-interrupts.js";import{resolveWebSearchBackend,resolveWebSearchProviderTool}from"#harness/provider-tools.js";const toolApprovals=new WeakMap;function buildToolSet(e){let t={},n=e.backgroundBatch??createBackgroundToolCallBatch(),r=e.capabilities?.requestInput===!0,i=e.disabledProviderTools;for(let a of e.tools.values()){if(a.behavior?.availability.includes(`requires-request-input`)===!0&&!r||i?.has(a.name))continue;n.setTool(a.name,a.execution===`background`&&a.execute!==void 0?{execute:a.execute,executeInput:a.executeInput,name:a.name,nodeId:a.nodeId,resultKind:a.resultKind,workflowId:a.workflowId}:void 0);let o=a.toModelOutput,s=buildApprovalFn(a,e),c=tool({description:a.description,execute:wrapToolExecute(a,n),inputSchema:a.inputSchema,...a.execution===`background`?{onInputAvailable:({input:e,toolCallId:t})=>{if(a.execute===void 0)throw Error(`Background tool "${a.name}" has no execute function.`);n.register({callId:t,input:e,toolName:a.name})}}:{},outputSchema:a.outputSchema,...a.execute===void 0?o===void 0?{}:{toModelOutput:async({output:e,toolCallId:t})=>normalizeToolModelOutput({output:await o(e),toolCallId:t,toolName:a.name})}:{toModelOutput:async({output:e,toolCallId:t})=>isAuthorizationPendingModelOutput(e)?{type:`text`,value:authorizationPendingModelText(e.connections)}:o===void 0?typeof e==`string`?{type:`text`,value:e}:normalizeToolModelOutput({output:{type:`json`,value:e??null},toolCallId:t,toolName:a.name}):normalizeToolModelOutput({output:await o(e),toolCallId:t,toolName:a.name})}});t[a.name]=c,a.approval!==void 0&&toolApprovals.set(c,s)}return t}function buildToolSetFromDefinitions(e){let t=new Map;for(let n of e.tools)t.has(n.name)||t.set(n.name,n);return buildToolSet({approvedTools:e.approvedTools,backgroundBatch:e.backgroundBatch,capabilities:e.capabilities,disabledProviderTools:e.disabledProviderTools,tools:t})}function wrapToolExecute(e,t=createBackgroundToolCallBatch()){let n=e.execute;if(n!==void 0)return(r,i)=>{let a;try{e.execution===`background`?(t.register({callId:i.toolCallId,input:r,toolName:e.name}),a=executeBackgroundToolCall({batch:t,definition:e,options:i,toolInput:r})):a=n(r,i)}catch(e){return Promise.reject(e)}return isAsyncIterable(a)?normalizeToolExecuteIterable(a,e.name,i):Promise.resolve(a).then(t=>normalizeToolExecuteOutput(t,e.name,i))}}async function*normalizeToolExecuteIterable(e,t,n){for await(let r of e)yield normalizeToolExecuteOutput(r,t,n)}function normalizeToolExecuteOutput(e,t,n){return isAuthorizationSignal(e)?(stashToolInterrupt(loadContext(),n.toolCallId,e),modelFacingAuthorizationOutput(e)):normalizeToolJsonOutput({boundary:`execute`,output:e,toolCallId:n.toolCallId,toolName:t})}async function buildToolSetWithProviderTools(e){let t=e.disabledProviderTools,n={...buildToolSet({approvedTools:e.approvedTools,backgroundBatch:e.backgroundBatch,capabilities:e.capabilities,disabledProviderTools:t,tools:e.tools})};for(let r of e.tools.values()){let i=r.behavior?.handling;if(i?.kind===`provider-tool`&&r.execute===void 0&&!t?.has(r.name)){let t=resolveWebSearchBackend(e.modelReference,i.provider);t===null?delete n[r.name]:n[r.name]=await resolveWebSearchProviderTool(t)}}return n}function buildApprovalFn(e,t){return async(n,r)=>{if(e.approval===void 0)return;let i=isObject(n)?n:void 0,a=await resolveApprovalPolicy(e.approval)({...buildCallbackContext(),approvedTools:t.approvedTools??new Set,callId:r,toolInput:i,toolName:e.name});return typeof a==`boolean`?a?`user-approval`:`not-applicable`:a}}function buildToolApproval(e){return async({toolCall:t})=>{let n=e[t.toolName];return n===void 0?void 0:await toolApprovals.get(n)?.(t.input,t.toolCallId)}}export{buildToolApproval,buildToolSet,buildToolSetFromDefinitions,buildToolSetWithProviderTools,wrapToolExecute};