UNPKG

eve

Version:

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

1 lines 3.35 kB
import{createLogger}from"#internal/logging.js";import{DynamicSkillManifestKey,SandboxKey}from"#context/keys.js";import{toErrorMessage}from"#shared/errors.js";import{ALLOWED_DYNAMIC_SKILL_EVENTS}from"#dynamic/definition.js";import{normalizeSkillPackage,removeSkillPackageFromSandbox,writeSkillPackageToSandbox}from"#shared/skill-package.js";import{ContextKey}from"#context/key.js";import{buildResolveContext}from"#context/dynamic-resolve-context.js";import{isBrandedSkillEntry}from"#shared/skill-definition.js";import{formatAvailableSkillsSection}from"#execution/skills/instructions.js";import{resolveSandboxSkillRoot}from"#shared/skill-paths.js";const log=createLogger(`dynamic-skills`);function qualifyDynamicSkillNames(e,t,n){let r=Object.keys(n),i=[];if(r.length===0)return i;if(t)return i.push({name:e.slug,entryKey:r[0],entry:n[r[0]]}),i;let a=e.extensionNamespace===void 0?``:`${e.extensionNamespace}__`;for(let e of r)i.push({name:`${a}${e}`,entryKey:e,entry:n[e]});return i}async function formatDynamicSkillAnnouncement(e){let t=await e.ctx.require(SandboxKey).get(),n=t===null?void 0:await resolveSandboxSkillRoot({sandbox:t});return formatAvailableSkillsSection(Object.values(e.manifest).flat(),{skillRoot:n})??``}const PendingSkillAnnouncementKey=new ContextKey(`eve.pendingSkillAnnouncement`);async function dispatchDynamicSkillEvent(e){let{ctx:t,resolvers:n,event:r,messages:i}=e;if(t.get(PendingSkillAnnouncementKey)===void 0){let e=t.get(DynamicSkillManifestKey);e!==void 0&&Object.keys(e).length>0&&t.setVirtualContext(PendingSkillAnnouncementKey,await formatDynamicSkillAnnouncement({ctx:t,manifest:e}))}if(!ALLOWED_DYNAMIC_SKILL_EVENTS.has(r.type))return;let a=n.filter(e=>e.eventNames.includes(r.type));if(a.length===0)return;let o=buildResolveContext(t,i),s=t.get(DynamicSkillManifestKey)??{},c=[],l=await Promise.allSettled(a.map(async e=>{let t=e.events[r.type];if(t===void 0)return null;let n=await t(r,o);if(n==null)return{resolver:e,named:[]};let i,a;return isBrandedSkillEntry(n)?(i={_single:n},a=!0):(i=n,a=!1),{resolver:e,named:qualifyDynamicSkillNames(e,a,i)}}));for(let e of l){if(e.status===`rejected`){log.error(`Dynamic skill resolver (${r.type}) threw — skipping.`,{error:toErrorMessage(e.reason)});continue}e.value!==null&&c.push({resolver:e.value.resolver,skills:e.value.named.map(({name:e,entry:t})=>normalizeSkillPackage({...t,name:e}))})}if(c.length===0)return;let u={...s};for(let{resolver:e,skills:t}of c)t.length===0?delete u[e.slug]:u[e.slug]=t.map(e=>({description:e.description,name:e.name}));let d=new Map;for(let[e,t]of Object.entries(u))for(let{name:n}of t){let t=d.get(n);if(t!==void 0)throw Error(`Dynamic skill "${n}" from resolver "${e}" collides with dynamic resolver "${t}". Namespace the map key manually, e.g. "${e}__${n}".`);d.set(n,e)}let f=await t.require(SandboxKey).get();if(f!==null){let e=new Set(Object.values(u).flat().map(e=>e.name)),t=new Set;for(let{resolver:n}of c)for(let r of s[n.slug]??[])e.has(r.name)||t.add(r.name);for(let e of t)await removeSkillPackageFromSandbox({name:e,sandbox:f});for(let{skills:e}of c)for(let t of e)await writeSkillPackageToSandbox({sandbox:f,skill:t})}t.set(DynamicSkillManifestKey,u),t.setVirtualContext(PendingSkillAnnouncementKey,await formatDynamicSkillAnnouncement({ctx:t,manifest:u}))}export{PendingSkillAnnouncementKey,dispatchDynamicSkillEvent};