UNPKG

eve

Version:

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

1 lines • 6.26 kB
import{fetchGatewayCatalog}from"../boxes/select-model.js";import{measureLoginStage,withLoginProgress}from"./model-login-progress.js";import{CONNECTION_OPTIONS,authenticateModelConnection,reuseModelConnection}from"./model-login-connection.js";import{changeValidatedAgentModel,readAuthoredModelSelection}from"./model-source-change.js";import{MODEL_CONNECTION_ENV}from"#internal/model-auth/transport.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{inspectApplication}from"#services/inspect-application.js";import{WizardCancelledError}from"#setup/step.js";import{MODEL_HELPERS,parseModelHelper}from"#shared/model-helper.js";import{providerSettingsMatch,readProviderKeySourceSync,readProviderSelection,readProviderTeamSync,resolveAvailableProviders,writeProviderSelection}from"#setup/provider-settings.js";import{resolveModelEndpointStatus}from"#internal/resolve-model-endpoint-status.js";import{classifyModelRouting}from"#internal/classify-model-routing.js";import{availableHelperModels}from"#internal/model-auth/available-models.js";import{isModelConnection,readDefaultConnection,writeDefaultConnection}from"#internal/model-auth/store.js";function environmentConnection(e){if(e.AI_GATEWAY_API_KEY?.trim())return`ai-gateway-key`;if(e.VERCEL_OIDC_TOKEN?.trim())return`ai-gateway-project`;if(e.OPENAI_API_KEY?.trim())return`openai`;if(e.ANTHROPIC_API_KEY?.trim())return`anthropic`}async function readLoginModel(e){let t=await readAuthoredModelSelection(e);if(t!==void 0)return{selection:t,external:parseModelHelper(t)!==void 0};let n=(await inspectApplication(e)).compiledState?.manifest.config.model;return{selection:n?.routing.kind===`gateway`&&n.source===void 0?n.id:void 0,external:n?.routing.kind===`external`}}function modelSelection(e,t){let n=e===`chatgpt`||e===`openai`||e===`anthropic`?e:void 0,r=t.selection===void 0?void 0:parseModelHelper(t.selection),i=n?r?.helper===n:t.selection!==void 0&&!t.external,a=n?MODEL_HELPERS[n].defaultModel:DEFAULT_AGENT_MODEL_ID,o=r?.id??t.selection;return{helper:n,compatible:i,defaultId:a,needsModels:!i||o===a}}async function applyConnection(e,t,n,r){let{appRoot:i,prompter:a,signal:o}=e,{selected:s,team:c}=t,{helper:l,compatible:u,defaultId:d,needsModels:f}=modelSelection(s,n),p;if(f){let e=t.availableModels??r??(l?await withLoginProgress(a,`Loading available models…`,()=>availableHelperModels(l,o)):[]),i=d;if(!e.includes(i)){if(e.length===0)throw Error(`No models are available for this connection. Choose another connection with /login.`);i=await a.select({message:`Choose an available model`,search:!0,options:e.map(e=>({value:e,label:e}))})}let s=l?MODEL_HELPERS[l].prefix+i:i;(!u||s!==n.selection)&&(p=s)}let m=s===`openai`||s===`anthropic`||s===`ai-gateway-key`?e.automatic?readProviderKeySourceSync(i)??(environmentConnection(process.env)===s?`environment`:`secret`):`secret`:void 0,h={selected:s,...c,keySource:m},g=!await providerSettingsMatch(i,h),save=async()=>{if(o?.throwIfAborted(),p!==void 0){let t=await changeValidatedAgentModel({appRoot:e.agentRoot??i,slug:p});if(t.kind===`rejected`)throw Error(t.message)}g&&await writeProviderSelection(i,s,c,m),process.env[MODEL_CONNECTION_ENV]=s,m?process.env.EVE_MODEL_KEY_SOURCE=m:delete process.env.EVE_MODEL_KEY_SOURCE,c?(process.env.EVE_MODEL_TEAM=c.teamId,process.env.EVE_MODEL_TEAM_NAME=c.teamName):(delete process.env.EVE_MODEL_TEAM,delete process.env.EVE_MODEL_TEAM_NAME)};p===void 0?await save():await withLoginProgress(a,`Loading selected model…`,()=>measureLoginStage(`activation`,()=>e.withConnectionUpdate?e.withConnectionUpdate(save):save())),e.automatic||await writeDefaultConnection(s);let _=p??n.selection,v=l&&_?parseModelHelper(_)?.id:_,y;if(v){let e=l?{kind:`external`,provider:MODEL_HELPERS[l].provider}:classifyModelRouting(v);y={id:v,routing:e,endpoint:resolveModelEndpointStatus(e,{apiKey:s===`ai-gateway-key`,oidc:s===`ai-gateway-project`,account:s===`vercel`||s===`vercel-cli`,team:c?.teamName},{state:`ready`})}}return{kind:`ready`,reload:p!==void 0&&e.withConnectionUpdate===void 0,...y&&{model:y}}}async function runModelLogin(e){let{appRoot:t,prompter:n,signal:r}=e,i,getModel=()=>i??=measureLoginStage(`source_inspection`,()=>readLoginModel(e.agentRoot??t)),connect=async(i,a)=>{let o=new AbortController,s=r?AbortSignal.any([r,o.signal]):o.signal,c=getModel().then(async e=>{let t=modelSelection(i,e);return{model:e,models:!t.helper&&t.needsModels?(await measureLoginStage(`gateway_catalog`,()=>fetchGatewayCatalog(s))).filter(e=>e.type===`language`).map(e=>e.id):void 0}}).then(e=>({value:e}),e=>({error:e}));try{let r=readProviderTeamSync(t),o=await measureLoginStage(`authentication`,async()=>a?await withLoginProgress(n,`Checking model access…`,()=>reuseModelConnection(i,r,s)):await authenticateModelConnection({selected:i,team:r,prompter:n,signal:s}));if(!o)return;let l=await withLoginProgress(n,`Loading available models…`,()=>c);if(`error`in l)throw l.error;return await applyConnection({...e,automatic:a,signal:s},o,l.value.model,l.value.models)}finally{o.abort()}};try{if(e.automatic){let{model:e,selected:a}=await withLoginProgress(n,`Reading saved connection…`,async()=>{let[e,n,r,i]=await Promise.all([getModel(),readProviderSelection(t),resolveAvailableProviders(t),readDefaultConnection()]),a=e.selection===void 0?void 0:parseModelHelper(e.selection)?.helper;return{model:e,selected:n??a??environmentConnection(process.env)??(r.includes(`ai-gateway-project`)?`ai-gateway-project`:void 0)??i??`vercel-cli`}});if(e.external&&e.selection===void 0)return{kind:`ready`,reload:!1};try{let e=await connect(a,!0);if(e)return e}catch(e){i=void 0,r?.throwIfAborted(),n.log.warning(e instanceof Error?e.message:`Could not connect automatically. Retry /login.`)}}for(;;){let e=await n.select({message:`Choose a connection`,search:!0,options:[...CONNECTION_OPTIONS]});if(!isModelConnection(e))throw Error(`Choose a model connection.`);try{let t=await connect(e,!1);if(t)return t}catch(e){if(i=void 0,e instanceof WizardCancelledError)return{kind:`cancelled`};r?.throwIfAborted(),n.log.warning(e instanceof Error?e.message:`Connection failed. Retry /login.`)}}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}export{environmentConnection,runModelLogin};