29
29
import org .springframework .ai .observation .conventions .AiProvider ;
30
30
import org .springframework .boot .context .properties .bind .ConstructorBinding ;
31
31
import org .springframework .http .HttpHeaders ;
32
+ import org .springframework .http .HttpMethod ;
32
33
import org .springframework .http .MediaType ;
34
+ import org .springframework .http .ResponseEntity ;
33
35
import org .springframework .http .client .ClientHttpResponse ;
34
36
import org .springframework .util .Assert ;
35
37
import org .springframework .util .StreamUtils ;
@@ -803,5 +805,159 @@ public EmbeddingResponse embeddings(EmbeddingRequest embeddingRequest) {
803
805
.body (EmbeddingResponse .class );
804
806
}
805
807
808
+ // --------------------------------------------------------------------------
809
+ // Models
810
+ // --------------------------------------------------------------------------
811
+
812
+ @ JsonInclude (Include .NON_NULL )
813
+ public record Model (
814
+ @ JsonProperty ("name" ) String name ,
815
+ @ JsonProperty ("model" ) String model ,
816
+ @ JsonProperty ("modified_at" ) Instant modifiedAt ,
817
+ @ JsonProperty ("size" ) Long size ,
818
+ @ JsonProperty ("digest" ) String digest ,
819
+ @ JsonProperty ("details" ) Details details
820
+ ) {
821
+ @ JsonInclude (Include .NON_NULL )
822
+ public record Details (
823
+ @ JsonProperty ("parent_model" ) String parentModel ,
824
+ @ JsonProperty ("format" ) String format ,
825
+ @ JsonProperty ("family" ) String family ,
826
+ @ JsonProperty ("families" ) List <String > families ,
827
+ @ JsonProperty ("parameter_size" ) String parameterSize ,
828
+ @ JsonProperty ("quantization_level" ) String quantizationLevel
829
+ ) {}
830
+ }
831
+
832
+ @ JsonInclude (Include .NON_NULL )
833
+ public record ListModelResponse (
834
+ @ JsonProperty ("models" ) List <Model > models
835
+ ) {}
836
+
837
+ /**
838
+ * List models that are available locally on the machine where Ollama is running.
839
+ */
840
+ public ListModelResponse listModels () {
841
+ return this .restClient .get ()
842
+ .uri ("/api/tags" )
843
+ .retrieve ()
844
+ .onStatus (this .responseErrorHandler )
845
+ .body (ListModelResponse .class );
846
+ }
847
+
848
+ @ JsonInclude (Include .NON_NULL )
849
+ public record ShowModelRequest (
850
+ @ JsonProperty ("model" ) String model ,
851
+ @ JsonProperty ("system" ) String system ,
852
+ @ JsonProperty ("verbose" ) Boolean verbose ,
853
+ @ JsonProperty ("options" ) Map <String , Object > options
854
+ ) {
855
+ public ShowModelRequest (String model ) {
856
+ this (model , null , null , null );
857
+ }
858
+ }
859
+
860
+ @ JsonInclude (Include .NON_NULL )
861
+ public record ShowModelResponse (
862
+ @ JsonProperty ("license" ) String license ,
863
+ @ JsonProperty ("modelfile" ) String modelfile ,
864
+ @ JsonProperty ("parameters" ) String parameters ,
865
+ @ JsonProperty ("template" ) String template ,
866
+ @ JsonProperty ("system" ) String system ,
867
+ @ JsonProperty ("details" ) Model .Details details ,
868
+ @ JsonProperty ("messages" ) List <Message > messages ,
869
+ @ JsonProperty ("model_info" ) Map <String , Object > modelInfo ,
870
+ @ JsonProperty ("projector_info" ) Map <String , Object > projectorInfo ,
871
+ @ JsonProperty ("modified_at" ) Instant modifiedAt
872
+ ) {}
873
+
874
+ /**
875
+ * Show information about a model available locally on the machine where Ollama is running.
876
+ */
877
+ public ShowModelResponse showModel (ShowModelRequest showModelRequest ) {
878
+ return this .restClient .post ()
879
+ .uri ("/api/show" )
880
+ .body (showModelRequest )
881
+ .retrieve ()
882
+ .onStatus (this .responseErrorHandler )
883
+ .body (ShowModelResponse .class );
884
+ }
885
+
886
+ @ JsonInclude (Include .NON_NULL )
887
+ public record CopyModelRequest (
888
+ @ JsonProperty ("source" ) String source ,
889
+ @ JsonProperty ("destination" ) String destination
890
+ ) {}
891
+
892
+ /**
893
+ * Copy a model. Creates a model with another name from an existing model.
894
+ */
895
+ public ResponseEntity <Void > copyModel (CopyModelRequest copyModelRequest ) {
896
+ return this .restClient .post ()
897
+ .uri ("/api/copy" )
898
+ .body (copyModelRequest )
899
+ .retrieve ()
900
+ .onStatus (this .responseErrorHandler )
901
+ .toBodilessEntity ();
902
+ }
903
+
904
+ @ JsonInclude (Include .NON_NULL )
905
+ public record DeleteModelRequest (
906
+ @ JsonProperty ("model" ) String model
907
+ ) {}
908
+
909
+ /**
910
+ * Delete a model and its data.
911
+ */
912
+ public ResponseEntity <Void > deleteModel (DeleteModelRequest deleteModelRequest ) {
913
+ return this .restClient .method (HttpMethod .DELETE )
914
+ .uri ("/api/delete" )
915
+ .body (deleteModelRequest )
916
+ .retrieve ()
917
+ .onStatus (this .responseErrorHandler )
918
+ .toBodilessEntity ();
919
+ }
920
+
921
+ @ JsonInclude (Include .NON_NULL )
922
+ public record PullModelRequest (
923
+ @ JsonProperty ("model" ) String model ,
924
+ @ JsonProperty ("insecure" ) Boolean insecure ,
925
+ @ JsonProperty ("username" ) String username ,
926
+ @ JsonProperty ("password" ) String password ,
927
+ @ JsonProperty ("stream" ) Boolean stream
928
+ ) {
929
+ public PullModelRequest {
930
+ if (stream != null && stream ) {
931
+ logger .warn ("Streaming when pulling models is not supported yet" );
932
+ }
933
+ stream = false ;
934
+ }
935
+
936
+ public PullModelRequest (String model ) {
937
+ this (model , null , null , null , null );
938
+ }
939
+ }
940
+
941
+ @ JsonInclude (Include .NON_NULL )
942
+ public record ProgressResponse (
943
+ @ JsonProperty ("status" ) String status ,
944
+ @ JsonProperty ("digest" ) String digest ,
945
+ @ JsonProperty ("total" ) Long total ,
946
+ @ JsonProperty ("completed" ) Long completed
947
+ ) {}
948
+
949
+ /**
950
+ * Download a model from the Ollama library. Cancelled pulls are resumed from where they left off,
951
+ * and multiple calls will share the same download progress.
952
+ */
953
+ public ProgressResponse pullModel (PullModelRequest pullModelRequest ) {
954
+ return this .restClient .post ()
955
+ .uri ("/api/pull" )
956
+ .body (pullModelRequest )
957
+ .retrieve ()
958
+ .onStatus (this .responseErrorHandler )
959
+ .body (ProgressResponse .class );
960
+ }
961
+
806
962
}
807
963
// @formatter:on
0 commit comments