@@ -13,8 +13,9 @@ use crate::model::params::LlamaModelParams;
13
13
use crate :: token:: LlamaToken ;
14
14
use crate :: token_type:: { LlamaTokenAttr , LlamaTokenAttrs } ;
15
15
use crate :: {
16
- ApplyChatTemplateError , ChatTemplateError , LlamaContextLoadError , LlamaLoraAdapterInitError ,
17
- LlamaModelLoadError , NewLlamaChatMessageError , StringToTokenError , TokenToStringError ,
16
+ ApplyChatTemplateError , ChatTemplateError , LlamaContextLoadError ,
17
+ LlamaLoraAdapterInitError , LlamaModelLoadError , MetaValError , NewLlamaChatMessageError ,
18
+ StringToTokenError , TokenToStringError ,
18
19
} ;
19
20
20
21
pub mod params;
@@ -490,6 +491,59 @@ impl LlamaModel {
490
491
u32:: try_from ( unsafe { llama_cpp_sys_2:: llama_model_n_head_kv ( self . model . as_ptr ( ) ) } ) . unwrap ( )
491
492
}
492
493
494
+ /// Get metadata value as a string by key name
495
+ pub fn meta_val_str ( & self , key : & str ) -> Result < String , MetaValError > {
496
+ let key_cstring = CString :: new ( key) ?;
497
+ let key_ptr = key_cstring. as_ptr ( ) ;
498
+
499
+ extract_meta_string (
500
+ |buf_ptr, buf_len| unsafe {
501
+ llama_cpp_sys_2:: llama_model_meta_val_str (
502
+ self . model . as_ptr ( ) ,
503
+ key_ptr,
504
+ buf_ptr,
505
+ buf_len,
506
+ )
507
+ } ,
508
+ 256 ,
509
+ )
510
+ }
511
+
512
+ /// Get the number of metadata key/value pairs
513
+ pub fn meta_count ( & self ) -> i32 {
514
+ unsafe { llama_cpp_sys_2:: llama_model_meta_count ( self . model . as_ptr ( ) ) }
515
+ }
516
+
517
+ /// Get metadata key name by index
518
+ pub fn meta_key_by_index ( & self , index : i32 ) -> Result < String , MetaValError > {
519
+ extract_meta_string (
520
+ |buf_ptr, buf_len| unsafe {
521
+ llama_cpp_sys_2:: llama_model_meta_key_by_index (
522
+ self . model . as_ptr ( ) ,
523
+ index,
524
+ buf_ptr,
525
+ buf_len,
526
+ )
527
+ } ,
528
+ 256 ,
529
+ )
530
+ }
531
+
532
+ /// Get metadata value as a string by index
533
+ pub fn meta_val_str_by_index ( & self , index : i32 ) -> Result < String , MetaValError > {
534
+ extract_meta_string (
535
+ |buf_ptr, buf_len| unsafe {
536
+ llama_cpp_sys_2:: llama_model_meta_val_str_by_index (
537
+ self . model . as_ptr ( ) ,
538
+ index,
539
+ buf_ptr,
540
+ buf_len,
541
+ )
542
+ } ,
543
+ 256 ,
544
+ )
545
+ }
546
+
493
547
/// Returns the rope type of the model.
494
548
pub fn rope_type ( & self ) -> Option < RopeType > {
495
549
match unsafe { llama_cpp_sys_2:: llama_model_rope_type ( self . model . as_ptr ( ) ) } {
@@ -690,6 +744,42 @@ impl LlamaModel {
690
744
}
691
745
}
692
746
747
+ /// Generic helper function for extracting string values from the C API
748
+ /// This are specifically useful for the the metadata functions, where we pass in a buffer
749
+ /// to be populated by a string, not yet knowing if the buffer is large enough.
750
+ /// If the buffer was not large enough, we get the correct length back, which can be used to
751
+ /// construct a buffer of appropriate size.
752
+ fn extract_meta_string < F > ( c_function : F , capacity : usize ) -> Result < String , MetaValError >
753
+ where
754
+ F : Fn ( * mut c_char , usize ) -> i32 ,
755
+ {
756
+ let mut buffer = vec ! [ 0u8 ; capacity] ;
757
+
758
+ // call the foreign function
759
+ let result = c_function ( buffer. as_mut_ptr ( ) as * mut c_char , buffer. len ( ) ) ;
760
+ if result < 0 {
761
+ return Err ( MetaValError :: NegativeReturn ( result) ) ;
762
+ }
763
+
764
+ // check if the response fit in our buffer
765
+ let returned_len = result as usize ;
766
+ if returned_len >= capacity {
767
+ // buffer wasn't large enough, try again with the correct capacity.
768
+ return extract_meta_string ( c_function, returned_len + 1 ) ;
769
+ }
770
+
771
+ // verify null termination
772
+ debug_assert_eq ! (
773
+ buffer. get( returned_len) ,
774
+ Some ( & 0 ) ,
775
+ "should end with null byte"
776
+ ) ;
777
+
778
+ // resize, convert, and return
779
+ buffer. truncate ( returned_len) ;
780
+ Ok ( String :: from_utf8 ( buffer) ?)
781
+ }
782
+
693
783
impl Drop for LlamaModel {
694
784
fn drop ( & mut self ) {
695
785
unsafe { llama_cpp_sys_2:: llama_free_model ( self . model . as_ptr ( ) ) }
0 commit comments