@@ -525,6 +525,105 @@ export namespace Provider {
525525 } ,
526526 }
527527 } ) ,
528+ edenai : Effect . fnUntraced ( function * ( input : Info ) {
529+ const auth = yield * dep . auth ( input . id )
530+ const apiKey = yield * Effect . sync ( ( ) => {
531+ if ( auth ?. type === "api" ) return auth . key
532+ return Env . get ( "EDENAI_API_KEY" )
533+ } )
534+
535+ if ( ! apiKey ) {
536+ return { autoload : false }
537+ }
538+
539+ const options = {
540+ baseURL : "https://api.edenai.run/v3/llm" ,
541+ apiKey,
542+ }
543+
544+ return {
545+ autoload : true ,
546+ options,
547+ async discoverModels ( ) : Promise < Record < string , Model > > {
548+ log . info ( "edenai model discovery starting" )
549+ try {
550+ const res = await fetch ( "https://api.edenai.run/v3/llm/models" , {
551+ headers : { Authorization : `Bearer ${ apiKey } ` } ,
552+ signal : AbortSignal . timeout ( 10000 ) ,
553+ } )
554+ if ( ! res . ok ) throw new Error ( `HTTP ${ res . status } ` )
555+ const json = await res . json ( )
556+ const models : Record < string , Model > = { }
557+
558+ for ( const m of json . data || [ ] ) {
559+ const caps = m . capabilities || { }
560+ if ( ! caps . supports_function_calling ) continue
561+
562+ const p = m . pricing || { }
563+ const cost = {
564+ input : ( p . input_cost_per_token || 0 ) * 1000000 ,
565+ output : ( p . output_cost_per_token || 0 ) * 1000000 ,
566+ cache : {
567+ read : ( p . cache_read_input_token_cost || 0 ) * 1000000 ,
568+ write : ( p . cache_creation_input_token_cost || 0 ) * 1000000 ,
569+ } ,
570+ }
571+
572+ models [ m . id ] = {
573+ id : ModelID . make ( m . id ) ,
574+ providerID : ProviderID . make ( "edenai" ) ,
575+ name : m . model_name || m . id ,
576+ family : "" ,
577+ api : {
578+ id : m . id ,
579+ url : "https://api.edenai.run/v3/llm" ,
580+ npm : "@ai-sdk/openai-compatible" ,
581+ } ,
582+ status : "active" ,
583+ headers : { } ,
584+ options : { } ,
585+ cost,
586+ limit : {
587+ context : m . context_length || 128000 ,
588+ output : 4096 ,
589+ } ,
590+ capabilities : {
591+ temperature : true ,
592+ reasoning : ! ! caps . supports_reasoning ,
593+ attachment : false ,
594+ toolcall : true ,
595+ input : {
596+ text : ( caps . input_modalities || [ ] ) . includes ( "text" ) ,
597+ audio : ( caps . input_modalities || [ ] ) . includes ( "audio" ) ,
598+ image : ( caps . input_modalities || [ ] ) . includes ( "image" ) ,
599+ video : ( caps . input_modalities || [ ] ) . includes ( "video" ) ,
600+ pdf : false ,
601+ } ,
602+ output : {
603+ text : ( caps . output_modalities || [ ] ) . includes ( "text" ) ,
604+ audio : ( caps . output_modalities || [ ] ) . includes ( "audio" ) ,
605+ image : ( caps . output_modalities || [ ] ) . includes ( "image" ) ,
606+ video : ( caps . output_modalities || [ ] ) . includes ( "video" ) ,
607+ pdf : false ,
608+ } ,
609+ interleaved : false ,
610+ } ,
611+ release_date : m . created ? new Date ( m . created * 1000 ) . toISOString ( ) : "" ,
612+ variants : { } ,
613+ }
614+ }
615+
616+ log . info ( "edenai model discovery complete" , {
617+ count : Object . keys ( models ) . length ,
618+ } )
619+ return models
620+ } catch ( e ) {
621+ log . warn ( "edenai model discovery failed" , { error : e } )
622+ return { }
623+ }
624+ } ,
625+ }
626+ } ) ,
528627 zenmux : ( ) =>
529628 Effect . succeed ( {
530629 autoload : false ,
@@ -1041,6 +1140,17 @@ export namespace Provider {
10411140 const modelsDev = yield * Effect . promise ( ( ) => ModelsDev . get ( ) )
10421141 const database = mapValues ( modelsDev , fromModelsDevProvider )
10431142
1143+ if ( ! database [ "edenai" ] ) {
1144+ database [ "edenai" ] = {
1145+ id : ProviderID . make ( "edenai" ) ,
1146+ name : "Eden AI" ,
1147+ source : "custom" ,
1148+ env : [ "EDENAI_API_KEY" ] ,
1149+ options : { baseURL : "https://api.edenai.run/v3/llm" } ,
1150+ models : { } ,
1151+ }
1152+ }
1153+
10441154 const providers : Record < ProviderID , Info > = { } as Record < ProviderID , Info >
10451155 const languages = new Map < string , LanguageModelV3 > ( )
10461156 const modelLoaders : {
0 commit comments