eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
2 lines • 8.74 kB
JavaScript
import{formatRegistrySessionResult,registryItemProgress,registryResultTone}from"./registry-result-message.js";import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{runModelLogin}from"#setup/flows/model-login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{runModelFlow}from"#setup/flows/model.js";import{RegistryFlowFailedError,runRegistryFlow}from"#setup/flows/registry.js";const SETUP_FLOW_CONFIG={login:{title:`Connecting your model`,indicator:`pulse`},model:{title:`Configure the agent model`,indicator:`pulse`},add:{title:`Add to your agent`,indicator:`pulse`},deploy:{title:`Deploy to Vercel`,indicator:`spinner`}};function muteableRenderer(e,t,n){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readModelPicker:n=>t()?Promise.resolve(void 0):e.readModelPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setNavigation:n=>{t()||e.setNavigation?.(n)},setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,r)=>{(!t()||r===`warning`||r===`error`)&&e.renderLine(n,r)},replaceContent:n=>{t()||e.replaceContent?.(n)},renderOutput:n=>{t()||e.renderOutput(n)},withInheritedStdio:t=>e.withInheritedStdio(t),withExclusiveTerminal:e=>n?.(e)??e()}}function cancelledSetupResult(){return{message:``,cancelled:!0,preserveFlowDiagnostics:!1}}async function runTuiSetupCommand(e){let{command:t}=e,n=!1,r=new AbortController,i=muteableRenderer(e.renderer,()=>n,e.withExclusiveTerminal),a=(e.createPrompter??createTuiPrompter)(i),cancelActiveRegistryItem,runRegistryItem=async e=>{let t=new AbortController;cancelActiveRegistryItem=()=>t.abort(new WizardCancelledError);try{return await e(AbortSignal.any([r.signal,t.signal]))}finally{cancelActiveRegistryItem=void 0}},o=e.renderer.waitForInterrupt(),s=executeSetupCommand(e,a,i,r.signal,runRegistryItem),c=s.then(e=>({kind:`outcome`,value:e}));try{for(;;){let i=!1;try{let e=await Promise.race([c,o.promise.then(e=>({kind:`interrupt`,interrupt:e}))]);if(e.kind===`outcome`)return e.value;if(t===`add`&&e.interrupt===`escape`&&cancelActiveRegistryItem!==void 0)cancelActiveRegistryItem(),i=!0;else{n=!0,r.abort(new WizardCancelledError);let e=await s;return e.partial===!0?e:{...e,...cancelledSetupResult(),tone:void 0}}}finally{o.dispose()}i&&(o=e.renderer.waitForInterrupt())}}finally{e.renderer.setStatus(void 0)}}async function executeSetupCommand(e,t,n,r,i){let{command:a,appRoot:o}=e,s={runInstallVercelCliFlow,runModelFlow,runRegistryFlow,runDeployFlow,...e.flows};try{switch(a){case`login`:{let n=await(s.runModelLogin??runModelLogin)({appRoot:o,agentRoot:e.agentRoot,prompter:t,signal:r,automatic:e.initialModelStep===`provider`,withConnectionUpdate:e.withExclusiveTerminal});return n.kind===`cancelled`?{message:`Connect a model with /login when you’re ready.`,cancelled:!0,preserveFlowDiagnostics:!1}:{message:`Connected. Start chatting · /add to extend your agent`,effect:{kind:`model-access-changed`,reload:n.reload,...n.model&&{model:n.model}},preserveFlowDiagnostics:!1}}case`model`:{let i={appRoot:e.agentRoot??o,environmentRoot:o,prompter:t,signal:r,chatGptAccountLabel:e.chatGptAccountLabel,deps:{pickModelSettings:e=>n.readModelPicker(e)}};e.initialModelStep!==void 0&&(i.initialStep=e.initialModelStep),e.onOnboardingScreen!==void 0&&(i.onScreen=t=>e.onOnboardingScreen?.({screen:t}));let a=await s.runModelFlow(i);if(a.kind===`cancelled`)return cancelledSetupResult();let c=[];a.modelMessage!==void 0&&c.push(a.modelMessage),a.providerSelection!==void 0&&c.push(providerSelectionMessage(a.providerSelection));let l={message:c.join(`
`),preserveFlowDiagnostics:!1};return a.accessChanged&&(l.effect={kind:`model-access-changed`,reload:!0}),l}case`add`:{let a=await s.runRegistryFlow({appRoot:o,installRoot:e.agentRoot,prompter:t,signal:r,initialAddress:e.initialRegistryAddress,onScreen:e.onOnboardingScreen,onItemStart:registryItemProgress(n),runItem:i});if(a.kind===`cancelled`)return cancelledSetupResult();let c=a.result,l=registryResultTone(c),u=c.items.length>0||c.failures.length>0||c.outcomes!==void 0?formatRegistrySessionResult(c):`No integrations selected.`,d={message:l===`error`?`/add failed — ${u}`:u,preserveFlowDiagnostics:!0};return c.cancelled===!0?(d.partial=!0,d.tone=`error`):l!==void 0&&(d.tone=l),c.deployed===`production`&&(d.effect={kind:`deployed`}),d}case`deploy`:{let e=await s.runDeployFlow({appRoot:o,prompter:t,interactive:!0,signal:r});return e.kind===`cancelled`?cancelledSetupResult():e.kind===`needs-link`?{message:`Not linked to a Vercel project. Run eve deploy in an interactive terminal to link it.`,preserveFlowDiagnostics:!0}:e.kind===`local-model`?{message:`ChatGPT subscription models are local-only. Switch to an AI Gateway or server-authenticated model before deploying.`,preserveFlowDiagnostics:!0}:{message:e.productionUrl===void 0?`Deployed.`:`Deployed: ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return cancelledSetupResult();let n=e instanceof RegistryFlowFailedError?e.cause:e,i=await vercelCliUpgradeOutcome(n,a,s,{appRoot:o,prompter:t,signal:r});if(i!==void 0)return withRegistryResults(i,e);let c=vercelActionOutcome(n,a);return c===void 0?e instanceof RegistryFlowFailedError?{message:`${formatRegistrySessionResult(e.completed)}\n\n${e.message}`,partial:!0,tone:`error`,preserveFlowDiagnostics:!0}:{message:`/${a} failed: ${e instanceof Error?e.message:String(e)}`,tone:`error`,preserveFlowDiagnostics:!0}:withRegistryResults(c,e)}}function withRegistryResults(e,t){return t instanceof RegistryFlowFailedError?{...e,message:`${formatRegistrySessionResult(t.completed)}\n\n${e.message}`,partial:!0,tone:`error`,preserveFlowDiagnostics:!0}:e}async function vercelCliUpgradeOutcome(e,t,n,r){if(!(e instanceof HumanActionRequiredError)||e.action.kind!==`vercel-cli-upgrade`)return;let i;try{i=await r.prompter.select({message:`Your Vercel CLI needs an update to list your teams. Upgrade now?`,options:[{value:`upgrade`,label:`Upgrade Vercel CLI`,description:`Run the Vercel CLI's native upgrader`},{value:`later`,label:`Not now`}],initialValue:`upgrade`})}catch{i=`later`}if(i===`later`)return{message:`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`,tone:`error`,preserveFlowDiagnostics:!0};let a;try{a=await n.runInstallVercelCliFlow({appRoot:r.appRoot,prompter:r.prompter,signal:r.signal,upgrade:!0})}catch(e){return{message:vercelCliUpgradeFailureMessage(t,errorMessage(e)),tone:`error`,preserveFlowDiagnostics:!0}}switch(a.kind){case`installed`:return{message:`Upgraded the Vercel CLI. Retry /${t}.`,tone:`error`,preserveFlowDiagnostics:!1};case`failed`:return{message:vercelCliUpgradeFailureMessage(t,a.reason),tone:`error`,preserveFlowDiagnostics:!0};case`cancelled`:return{message:`Vercel CLI upgrade cancelled — run \`vercel upgrade\`, then retry /${t}.`,tone:`error`,preserveFlowDiagnostics:!0};case`already`:return{message:`The Vercel CLI is already up to date. Retry /${t}.`,tone:`error`,preserveFlowDiagnostics:!1}}}function errorMessage(e){let t=(e instanceof Error?e.message:String(e)).replace(/\s+/gu,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}function vercelCliUpgradeFailureMessage(e,t){return`Couldn't upgrade the Vercel CLI${t===void 0||t===``?``:` (${t})`} — run \`vercel upgrade\`, then retry /${e}.`}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,tone:`error`,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /deploy to connect your Vercel account, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — check your team access and SSO, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /deploy to install it, then retry /${t}.`;case`vercel-cli-upgrade`:return`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`;default:return}}function providerSelectionMessage(e){return e===`chatgpt`?`ChatGPT subscription selected.`:e===`ai-gateway-project`?`AI Gateway via Project selected.`:`AI Gateway via API key selected.`}export{SETUP_FLOW_CONFIG,runTuiSetupCommand};