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