= Ollama Chat

With https://ollama.ai/[Ollama] you can run various Large Language Models (LLMs) locally and generate text from them.
Spring AI supports the Ollama chat completion capabilities with the `OllamaChatModel` API.

TIP: Ollama offers an OpenAI API compatible endpoint as well. 
The xref:_openai_api_compatibility[OpenAI API compatibility] section explains how to use the xref:api/chat/openai-chat.adoc[Spring AI OpenAI] to connect to an Ollama server.

== Prerequisites

You first need access to an Ollama instance. There are a few options, including the following:

* link:https://ollama.com/download[Download and install Ollama] on your local machine.
* Configure and xref:api/testcontainers.adoc[run Ollama via Testcontainers].
* Bind to an Ollama instance via xref:api/cloud-bindings.adoc[Kubernetes Service Bindings].

You can pull the models you want to use in your application from the link:https://ollama.com/library[Ollama model library]:

[source,shellscript]
----
ollama pull <model-name>
----

You can also pull any of the thousands, free, link:https://huggingface.co/models?library=gguf&sort=trending[GGUF Hugging Face Models]:

[source,shellscript]
----
ollama pull hf.co/<username>/<model-repository>
----

Alternatively, you can enable the option to download automatically any needed model: xref:auto-pulling-models[Auto-pulling Models].

== Auto-configuration

[NOTE]
====
There has been a significant change in the Spring AI auto-configuration, starter modules' artifact names.
Please refer to the https://docs.spring.io/spring-ai/reference/upgrade-notes.html[upgrade notes] for more information.
====

Spring AI provides Spring Boot auto-configuration for the Ollama chat integration.
To enable it add the following dependency to your project's Maven `pom.xml` or Gradle `build.gradle` build files:

[tabs]
======
Maven::
+
[source,xml]
----
<dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
----

Gradle::
+
[source,groovy]
----
dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
}
----
======

TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.

=== Base Properties

The prefix `spring.ai.ollama` is the property prefix to configure the connection to Ollama.

[cols="3,6,1", stripes=even]
|====
| Property | Description | Default
| spring.ai.ollama.base-url | Base URL where Ollama API server is running. | `http://localhost:11434`
|====

Here are the properties for initializing the Ollama integration and xref:auto-pulling-models[auto-pulling models].

[cols="3,6,1"]
|====
| Property | Description | Default
| spring.ai.ollama.init.pull-model-strategy | Whether to pull models at startup-time and how. | `never`
| spring.ai.ollama.init.timeout | How long to wait for a model to be pulled. | `5m`
| spring.ai.ollama.init.max-retries | Maximum number of retries for the model pull operation. | `0`
| spring.ai.ollama.init.chat.include | Include this type of models in the initialization task. | `true`
| spring.ai.ollama.init.chat.additional-models | Additional models to initialize besides the ones configured via default properties. | `[]`
|====

=== Chat Properties

[NOTE]
====
Enabling and disabling of the chat auto-configurations are now configured via top level properties with the prefix `spring.ai.model.chat`.

To enable, spring.ai.model.chat=ollama (It is enabled by default)

To disable, spring.ai.model.chat=none (or any value which doesn't match ollama)

This change is done to allow configuration of multiple models.
====

The prefix `spring.ai.ollama.chat.options` is the property prefix that configures the Ollama chat model.
It includes the Ollama request (advanced) parameters such as the `model`, `keep-alive`, and `format` as well as the Ollama model `options` properties.

Here are the advanced request parameter for the Ollama chat model:

[cols="3,6,1", stripes=even]
|====
| Property | Description | Default
| spring.ai.ollama.chat.enabled (Removed and no longer valid)     | Enable Ollama chat model. | true
| spring.ai.model.chat      | Enable Ollama chat model. | ollama
| spring.ai.ollama.chat.options.model  | The name of the https://github.com/ollama/ollama?tab=readme-ov-file#model-library[supported model] to use. | mistral
| spring.ai.ollama.chat.options.format  | The format to return a response in. Currently, the only accepted value is `json` | -
| spring.ai.ollama.chat.options.keep_alive  | Controls how long the model will stay loaded into memory following the request | 5m
|====

The remaining `options` properties are based on the link:https://github.com/ollama/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values[Ollama Valid Parameters and Values] and link:https://github.com/ollama/ollama/blob/main/api/types.go[Ollama Types]. The default values are based on the link:https://github.com/ollama/ollama/blob/b538dc3858014f94b099730a592751a5454cab0a/api/types.go#L364[Ollama Types Defaults].

[cols="3,6,1", stripes=even]
|====
| Property | Description | Default
| spring.ai.ollama.chat.options.numa              | Whether to use NUMA.                                           | false
| spring.ai.ollama.chat.options.num-ctx           | Sets the size of the context window used to generate the next token. | 2048
| spring.ai.ollama.chat.options.num-batch         | Prompt processing maximum batch size. | 512
| spring.ai.ollama.chat.options.num-gpu           | The number of layers to send to the GPU(s). On macOS it defaults to 1 to enable metal support, 0 to disable. 1 here indicates that NumGPU should be set dynamically | -1
| spring.ai.ollama.chat.options.main-gpu          | When using multiple GPUs this option controls which GPU is used for small tensors for which the overhead of splitting the computation across all GPUs is not worthwhile. The GPU in question will use slightly more VRAM to store a scratch buffer for temporary results. | 0
| spring.ai.ollama.chat.options.low-vram          | -                                                             | false
| spring.ai.ollama.chat.options.f16-kv            | -                                                             | true
| spring.ai.ollama.chat.options.logits-all        | Return logits for all the tokens, not just the last one. To enable completions to return logprobs, this must be true. | -
| spring.ai.ollama.chat.options.vocab-only        | Load only the vocabulary, not the weights. | -
| spring.ai.ollama.chat.options.use-mmap          | By default, models are mapped into memory, which allows the system to load only the necessary parts of the model as needed. However, if the model is larger than your total amount of RAM or if your system is low on available memory, using mmap might increase the risk of pageouts, negatively impacting performance. Disabling mmap results in slower load times but may reduce pageouts if you're not using mlock. Note that if the model is larger than the total amount of RAM, turning off mmap would prevent the model from loading at all. | null
| spring.ai.ollama.chat.options.use-mlock         | Lock the model in memory, preventing it from being swapped out when memory-mapped. This can improve performance but trades away some of the advantages of memory-mapping by requiring more RAM to run and potentially slowing down load times as the model loads into RAM. | false
| spring.ai.ollama.chat.options.num-thread        | Sets the number of threads to use during computation. By default, Ollama will detect this for optimal performance. It is recommended to set this value to the number of physical CPU cores your system has (as opposed to the logical number of cores). 0 = let the runtime decide | 0
| spring.ai.ollama.chat.options.num-keep          | -                                                             | 4
| spring.ai.ollama.chat.options.seed              | Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt.  | -1
| spring.ai.ollama.chat.options.num-predict       | Maximum number of tokens to predict when generating text. (-1 = infinite generation, -2 = fill context) | -1
| spring.ai.ollama.chat.options.top-k             | Reduces the probability of generating nonsense. A higher value (e.g., 100) will give more diverse answers, while a lower value (e.g., 10) will be more conservative.  | 40
| spring.ai.ollama.chat.options.top-p             | Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text.  | 0.9
| spring.ai.ollama.chat.options.min-p             | Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out.  | 0.0
| spring.ai.ollama.chat.options.tfs-z             | Tail-free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. | 1.0
| spring.ai.ollama.chat.options.typical-p         | -                                                             | 1.0
| spring.ai.ollama.chat.options.repeat-last-n     | Sets how far back for the model to look back to prevent repetition. (Default: 64, 0 = disabled, -1 = num_ctx) | 64
| spring.ai.ollama.chat.options.temperature       | The temperature of the model. Increasing the temperature will make the model answer more creatively. | 0.8
| spring.ai.ollama.chat.options.repeat-penalty    | Sets how strongly to penalize repetitions. A higher value (e.g., 1.5) will penalize repetitions more strongly, while a lower value (e.g., 0.9) will be more lenient. | 1.1
| spring.ai.ollama.chat.options.presence-penalty  | -                                                             | 0.0
| spring.ai.ollama.chat.options.frequency-penalty | -                                                             | 0.0
| spring.ai.ollama.chat.options.mirostat          | Enable Mirostat sampling for controlling perplexity. (default: 0, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0) | 0
| spring.ai.ollama.chat.options.mirostat-tau      | Controls the balance between coherence and diversity of the output. A lower value will result in more focused and coherent text. | 5.0
| spring.ai.ollama.chat.options.mirostat-eta      | Influences how quickly the algorithm responds to feedback from the generated text. A lower learning rate will result in slower adjustments, while a higher learning rate will make the algorithm more responsive. | 0.1
| spring.ai.ollama.chat.options.penalize-newline  | -                                                             | true
| spring.ai.ollama.chat.options.stop              | Sets the stop sequences to use. When this pattern is encountered the LLM will stop generating text and return. Multiple stop patterns may be set by specifying multiple separate stop parameters in a modelfile. | -
| spring.ai.ollama.chat.options.functions         | List of functions, identified by their names, to enable for function calling in a single prompt requests. Functions with those names must exist in the functionCallbacks registry. | -
| spring.ai.ollama.chat.options.proxy-tool-calls  | If true, the Spring AI will not handle the function calls internally, but will proxy them to the client. Then is the client's responsibility to handle the function calls, dispatch them to the appropriate function, and return the results. If false (the default), the Spring AI will handle the function calls internally. Applicable only for chat models with function calling support | false
|====

TIP: All properties prefixed with `spring.ai.ollama.chat.options` can be overridden at runtime by adding request-specific <<chat-options>> to the `Prompt` call.

== Runtime Options [[chat-options]]

The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions.java] class provides model configurations, such as the model to use, the temperature,  etc.

On start-up, the default options can be configured with the `OllamaChatModel(api, options)` constructor or the `spring.ai.ollama.chat.options.*` properties.

At run-time, you can override the default options by adding new, request-specific options to the `Prompt` call.
For example, to override the default model and temperature for a specific request:

[source,java]
----
ChatResponse response = chatModel.call(
    new Prompt(
        "Generate the names of 5 famous pirates.",
        OllamaOptions.builder()
            .model(OllamaModel.LLAMA3_1)
            .temperature(0.4)
            .build()
    ));
----

TIP: In addition to the model specific link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaOptions.java[OllamaOptions] you can use a portable link:https://github.com/spring-projects/spring-ai/blob/main/spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/ChatOptions.java[ChatOptions] instance, created with link:https://github.com/spring-projects/spring-ai/blob/main/spring-ai-model/src/main/java/org/springframework/ai/chat/prompt/DefaultChatOptionsBuilder.java[ChatOptions#builder()].

[[auto-pulling-models]]
== Auto-pulling Models

Spring AI Ollama can automatically pull models when they are not available in your Ollama instance.
This feature is particularly useful for development and testing as well as for deploying your applications to new environments.

TIP: You can also pull, by name, any of the thousands, free, link:https://huggingface.co/models?library=gguf&sort=trending[GGUF Hugging Face Models].

There are three strategies for pulling models:

* `always` (defined in `PullModelStrategy.ALWAYS`): Always pull the model, even if it's already available. Useful to ensure you're using the latest version of the model.
* `when_missing` (defined in `PullModelStrategy.WHEN_MISSING`): Only pull the model if it's not already available. This may result in using an older version of the model.
* `never` (defined in `PullModelStrategy.NEVER`): Never pull the model automatically.

CAUTION: Due to potential delays while downloading models, automatic pulling is not recommended for production environments. Instead, consider assessing and pre-downloading the necessary models in advance.

All models defined via configuration properties and default options can be automatically pulled at startup time.
You can configure the pull strategy, timeout, and maximum number of retries using configuration properties:

[source,yaml]
----
spring:
  ai:
    ollama:
      init:
        pull-model-strategy: always
        timeout: 60s
        max-retries: 1
----

CAUTION: The application will not complete its initialization until all specified models are available in Ollama. Depending on the model size and internet connection speed, this may significantly slow down your application's startup time.

You can initialize additional models at startup, which is useful for models used dynamically at runtime:

[source,yaml]
----
spring:
  ai:
    ollama:
      init:
        pull-model-strategy: always
        chat:
          additional-models:
            - llama3.2
            - qwen2.5
----

If you want to apply the pulling strategy only to specific types of models, you can exclude chat models from the initialization task:

[source,yaml]
----
spring:
  ai:
    ollama:
      init:
        pull-model-strategy: always
        chat:
          include: false
----

This configuration will apply the pulling strategy to all models except chat models.

== Function Calling

You can register custom Java functions with the `OllamaChatModel` and have the Ollama model intelligently choose to output a JSON object containing arguments to call one or many of the registered functions.
This is a powerful technique to connect the LLM capabilities with external tools and APIs.
Read more about xref:api/tools.adoc[Tool Calling].

TIP: You need Ollama 0.2.8 or newer to use the functional calling capabilities and Ollama 0.4.6 or newer to use them in streaming mode.

== Multimodal

Multimodality refers to a model's ability to simultaneously understand and process information from various sources, including text, images, audio, and other data formats.

Some of the models available in Ollama with multimodality support are https://ollama.com/library/llava[LLaVA] and https://ollama.com/library/bakllava[BakLLaVA] (see the link:https://ollama.com/search?c=vision[full list]).
For further details, refer to the link:https://llava-vl.github.io/[LLaVA: Large Language and Vision Assistant].

The Ollama link:https://github.com/ollama/ollama/blob/main/docs/api.md#parameters-1[Message API] provides an "images" parameter to incorporate a list of base64-encoded images with the message.

Spring AI’s link:https://github.com/spring-projects/spring-ai/blob/main/spring-ai-model/src/main/java/org/springframework/ai/chat/messages/Message.java[Message] interface facilitates multimodal AI models by introducing the link:https://github.com/spring-projects/spring-ai/blob/main/spring-ai-commons/src/main/java/org/springframework/ai/content/Media.java[Media] type.
This type encompasses data and details regarding media attachments in messages, utilizing Spring’s `org.springframework.util.MimeType` and a `org.springframework.core.io.Resource` for the raw media data.

Below is a straightforward code example excerpted from link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/OllamaChatModelMultimodalIT.java[OllamaChatModelMultimodalIT.java], illustrating the fusion of user text with an image.

[source,java]
----
var imageResource = new ClassPathResource("/multimodal.test.png");

var userMessage = new UserMessage("Explain what do you see on this picture?",
        new Media(MimeTypeUtils.IMAGE_PNG, this.imageResource));

ChatResponse response = chatModel.call(new Prompt(this.userMessage,
        OllamaOptions.builder().model(OllamaModel.LLAVA)).build());
----

The example shows a model taking as an input the `multimodal.test.png` image:

image::multimodal.test.png[Multimodal Test Image, 200, 200, align="left"]

along with the text message "Explain what do you see on this picture?", and generating a response like this:

----
The image shows a small metal basket filled with ripe bananas and red apples. The basket is placed on a surface,
which appears to be a table or countertop, as there's a hint of what seems like a kitchen cabinet or drawer in
the background. There's also a gold-colored ring visible behind the basket, which could indicate that this
photo was taken in an area with metallic decorations or fixtures. The overall setting suggests a home environment
where fruits are being displayed, possibly for convenience or aesthetic purposes.
----

== Structured Outputs

Ollama provides custom https://ollama.com/blog/structured-outputs[Structured Outputs] APIs that ensure your model generates responses conforming strictly to your provided `JSON Schema`.
In addition to the existing Spring AI model-agnostic xref::api/structured-output-converter.adoc[Structured Output Converter], these APIs offer enhanced control and precision.

=== Configuration

Spring AI allows you to configure your response format programmatically using the `OllamaOptions` builder.

==== Using the Chat Options Builder

You can set the response format programmatically with the `OllamaOptions` builder as shown below:

[source,java]
----
String jsonSchema = """
        {
            "type": "object",
            "properties": {
                "steps": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "explanation": { "type": "string" },
                            "output": { "type": "string" }
                        },
                        "required": ["explanation", "output"],
                        "additionalProperties": false
                    }
                },
                "final_answer": { "type": "string" }
            },
            "required": ["steps", "final_answer"],
            "additionalProperties": false
        }
        """;

Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
        OllamaOptions.builder()
            .model(OllamaModel.LLAMA3_2.getName())
            .format(new ObjectMapper().readValue(jsonSchema, Map.class))
            .build());

ChatResponse response = this.ollamaChatModel.call(this.prompt);
----

==== Integrating with BeanOutputConverter Utilities

You can leverage existing xref::api/structured-output-converter.adoc#_bean_output_converter[BeanOutputConverter] utilities to automatically generate the JSON Schema from your domain objects and later convert the structured response into domain-specific instances:

[source,java]
----
record MathReasoning(
    @JsonProperty(required = true, value = "steps") Steps steps,
    @JsonProperty(required = true, value = "final_answer") String finalAnswer) {

    record Steps(
        @JsonProperty(required = true, value = "items") Items[] items) {

        record Items(
            @JsonProperty(required = true, value = "explanation") String explanation,
            @JsonProperty(required = true, value = "output") String output) {
        }
    }
}

var outputConverter = new BeanOutputConverter<>(MathReasoning.class);

Prompt prompt = new Prompt("how can I solve 8x + 7 = -23",
        OllamaOptions.builder()
            .model(OllamaModel.LLAMA3_2.getName())
            .format(outputConverter.getJsonSchemaMap())
            .build());

ChatResponse response = this.ollamaChatModel.call(this.prompt);
String content = this.response.getResult().getOutput().getText();

MathReasoning mathReasoning = this.outputConverter.convert(this.content);
----

NOTE: Ensure you use the `@JsonProperty(required = true,...)`  annotation for generating a schema that accurately marks fields as `required`.
Although this is optional for JSON Schema, it's recommended for the structured response to function correctly.

== OpenAI API Compatibility

Ollama is OpenAI API-compatible and you can use the xref:api/chat/openai-chat.adoc[Spring AI OpenAI] client to talk to Ollama and use tools.
For this, you need to configure the OpenAI base URL to your Ollama instance: `spring.ai.openai.chat.base-url=http://localhost:11434` and select one of the provided Ollama models: `spring.ai.openai.chat.options.model=mistral`.

image::spring-ai-ollama-over-openai.jpg[Ollama OpenAI API compatibility, 800, 600, align="center"]

Check the link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/proxy/OllamaWithOpenAiChatModelIT.java[OllamaWithOpenAiChatModelIT.java] tests for examples of using Ollama over Spring AI OpenAI.

== HuggingFace Models

Ollama can access, out of the box, all https://huggingface.co/models?library=gguf&sort=trending[GGUF Hugging Face ] Chat Models.
You can pull any of these models by name: `ollama pull hf.co/<username>/<model-repository>` or configure the auto-pulling strategy: xref:auto-pulling-models[Auto-pulling Models]:

[source]
----
spring.ai.ollama.chat.options.model=hf.co/bartowski/gemma-2-2b-it-GGUF
spring.ai.ollama.init.pull-model-strategy=always
----

- `spring.ai.ollama.chat.options.model`: Specifies the https://huggingface.co/models?library=gguf&sort=trending[Hugging Face GGUF model] to use. 
- `spring.ai.ollama.init.pull-model-strategy=always`: (optional) Enables automatic model pulling at startup time. 
For production, you should pre-download the models to avoid delays: `ollama pull hf.co/bartowski/gemma-2-2b-it-GGUF`.

== Sample Controller

https://start.spring.io/[Create] a new Spring Boot project and add the `spring-ai-starter-model-ollama` to your pom (or gradle) dependencies.

Add a `application.yaml` file, under the `src/main/resources` directory, to enable and configure the Ollama chat model:

[source,yaml]
----
spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        options:
          model: mistral
          temperature: 0.7
----

TIP: Replace the `base-url` with your Ollama server URL.

This will create an `OllamaChatModel` implementation that you can inject into your classes.
Here is an example of a simple `@RestController` class that uses the chat model for text generations.

[source,java]
----
@RestController
public class ChatController {

    private final OllamaChatModel chatModel;

    @Autowired
    public ChatController(OllamaChatModel chatModel) {
        this.chatModel = chatModel;
    }

    @GetMapping("/ai/generate")
    public Map<String,String> generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", this.chatModel.call(message));
    }

    @GetMapping("/ai/generateStream")
	public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        Prompt prompt = new Prompt(new UserMessage(message));
        return this.chatModel.stream(prompt);
    }

}
----

== Manual Configuration

If you don't want to use the Spring Boot auto-configuration, you can manually configure the `OllamaChatModel` in your application.
The https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/OllamaChatModel.java[OllamaChatModel] implements the `ChatModel` and `StreamingChatModel` and uses the <<low-level-api>> to connect to the Ollama service.

To use it, add the `spring-ai-ollama` dependency to your project's Maven `pom.xml` or Gradle `build.gradle` build files:

[tabs]
======
Maven::
+
[source,xml]
----
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-ollama</artifactId>
</dependency>
----

Gradle::
+
[source,groovy]
----
dependencies {
    implementation 'org.springframework.ai:spring-ai-ollama'
}
----
======

TIP: Refer to the xref:getting-started.adoc#dependency-management[Dependency Management] section to add the Spring AI BOM to your build file.

TIP: The `spring-ai-ollama` dependency provides access also to the `OllamaEmbeddingModel`.
For more information about the `OllamaEmbeddingModel` refer to the link:../embeddings/ollama-embeddings.html[Ollama Embedding Model] section.

Next, create an `OllamaChatModel` instance and use it to send requests for text generation:

[source,java]
----
var ollamaApi = OllamaApi.builder().build();

var chatModel = OllamaChatModel.builder()
                    .ollamaApi(ollamaApi)
                    .defaultOptions(
                        OllamaOptions.builder()
                            .model(OllamaModel.MISTRAL)
                            .temperature(0.9)
                            .build())
                    .build();

ChatResponse response = this.chatModel.call(
    new Prompt("Generate the names of 5 famous pirates."));

// Or with streaming responses
Flux<ChatResponse> response = this.chatModel.stream(
    new Prompt("Generate the names of 5 famous pirates."));
----

The `OllamaOptions` provides the configuration information for all chat requests.

== Low-level OllamaApi Client [[low-level-api]]

The link:https://github.com/spring-projects/spring-ai/blob/main/models/spring-ai-ollama/src/main/java/org/springframework/ai/ollama/api/OllamaApi.java[OllamaApi] provides a lightweight Java client for the Ollama Chat Completion API link:https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-chat-completion[Ollama Chat Completion API].

The following class diagram illustrates the `OllamaApi` chat interfaces and building blocks:

image::ollama-chat-completion-api.jpg[OllamaApi Chat Completion API Diagram, 800, 600]

NOTE: The `OllamaApi` is a low-level API and is not recommended for direct use. Use the `OllamaChatModel` instead.

Here is a simple snippet showing how to use the API programmatically:

[source,java]
----
OllamaApi ollamaApi = new OllamaApi("YOUR_HOST:YOUR_PORT");

// Sync request
var request = ChatRequest.builder("orca-mini")
    .stream(false) // not streaming
    .messages(List.of(
            Message.builder(Role.SYSTEM)
                .content("You are a geography teacher. You are talking to a student.")
                .build(),
            Message.builder(Role.USER)
                .content("What is the capital of Bulgaria and what is the size? "
                        + "What is the national anthem?")
                .build()))
    .options(OllamaOptions.builder().temperature(0.9).build())
    .build();

ChatResponse response = this.ollamaApi.chat(this.request);

// Streaming request
var request2 = ChatRequest.builder("orca-mini")
    .ttream(true) // streaming
    .messages(List.of(Message.builder(Role.USER)
        .content("What is the capital of Bulgaria and what is the size? " + "What is the national anthem?")
        .build()))
    .options(OllamaOptions.builder().temperature(0.9).build().toMap())
    .build();

Flux<ChatResponse> streamingResponse = this.ollamaApi.streamingChat(this.request2);
----
