@@ -15,6 +15,9 @@ pub trait LocalLlmPluginExt<R: Runtime> {
1515 fn start_server ( & self ) -> impl Future < Output = Result < String , crate :: Error > > ;
1616 fn stop_server ( & self ) -> impl Future < Output = Result < ( ) , crate :: Error > > ;
1717
18+ fn list_downloaded_model (
19+ & self ,
20+ ) -> impl Future < Output = Result < Vec < crate :: SupportedModel > , crate :: Error > > ;
1821 fn get_current_model ( & self ) -> Result < crate :: SupportedModel , crate :: Error > ;
1922 fn set_current_model ( & self , model : crate :: SupportedModel ) -> Result < ( ) , crate :: Error > ;
2023
@@ -124,6 +127,40 @@ impl<R: Runtime, T: Manager<R>> LocalLlmPluginExt<R> for T {
124127 Ok ( ( ) )
125128 }
126129
130+ #[ tracing:: instrument( skip_all) ]
131+ async fn list_downloaded_model ( & self ) -> Result < Vec < crate :: SupportedModel > , crate :: Error > {
132+ let models_dir = self . models_dir ( ) ;
133+
134+ if !models_dir. exists ( ) {
135+ return Ok ( vec ! [ ] ) ;
136+ }
137+
138+ let mut models = Vec :: new ( ) ;
139+
140+ for entry in models_dir. read_dir ( ) ? {
141+ let entry = match entry {
142+ Ok ( e) => e,
143+ Err ( _) => {
144+ continue ;
145+ }
146+ } ;
147+
148+ let file_name = entry. file_name ( ) ;
149+ let file_name_str = file_name. to_string_lossy ( ) ;
150+
151+ if let Some ( model) = crate :: model:: SUPPORTED_MODELS
152+ . iter ( )
153+ . find ( |model| model. file_name ( ) == file_name_str)
154+ {
155+ if entry. path ( ) . is_file ( ) {
156+ models. push ( model. clone ( ) ) ;
157+ }
158+ }
159+ }
160+
161+ Ok ( models)
162+ }
163+
127164 #[ tracing:: instrument( skip_all) ]
128165 async fn start_server ( & self ) -> Result < String , crate :: Error > {
129166 let current_model = self . get_current_model ( ) ?;
0 commit comments