An LLM library for Java and Kotlin

LLM4S is written in Scala, and Java and Kotlin code can use it through two entry points: llm4s-java-api, a Java facade whose calls return a checked LlmResult instead of throwing, and llm4s-kotlin-api, suspend functions and Flows on top of it. Both call the same providers, tools and agents as the Scala API.

  1. Java
  2. Kotlin
  3. Spring Boot, Quarkus and the rest

Java

Add the facade and the provider module you call. The _3 suffix is the Scala version the artifacts are built for; Maven and Gradle need it written out.

1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>org.llm4s</groupId>
    <artifactId>llm4s-java-api_3</artifactId>
    <version>0.5.1</version>
</dependency>
<dependency>
    <groupId>org.llm4s</groupId>
    <artifactId>llm4s-openai_3</artifactId>
    <version>0.5.1</version>
</dependency>

A first call, with the provider configured in application.conf as on the configuration page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.PrintStream;

import org.llm4s.javaapi.JLlmClient;
import org.llm4s.javaapi.Llm4s;
import org.llm4s.javaapi.LlmResult;

public final class HelloLlm4s {

    private HelloLlm4s() {}

    public static void main(String[] args) {
        System.exit(run(System.out, System.err));
    }

    static int run(PrintStream out, PrintStream err) {
        LlmResult<JLlmClient> created = Llm4s.createDefaultClient();
        if (created.isFailure()) {
            err.println("Could not create a client: " + created.getError().getMessage());
            return 1;
        }

        // JLlmClient is AutoCloseable: it holds an HTTP client, so close it.
        try (JLlmClient client = created.get()) {
            LlmResult<String> answer = client.complete("What is a monad? Answer in one sentence.");
            answer
                .ifSuccess(text -> out.println(text))
                .ifFailure(error -> err.println("The call failed: " + error.getMessage()));
            return answer.isSuccess() ? 0 : 1;
        }
    }
}

The facade also streams replies, returns structured output as a Java record, defines tools with @Tool methods or a lambda builder, runs agents (JAgent) and has completeAsync and runAsync returning a CompletableFuture. Some Scala types still appear in its signatures; the Java guide says which. It needs JDK 21.

Kotlin

llm4s-kotlin-api has no _3 suffix: it is a Kotlin artifact, built with Gradle. It brings llm4s-java-api_3 and kotlinx-coroutines-core.

1
2
3
4
dependencies {
    implementation("org.llm4s:llm4s-kotlin-api:0.5.1")
    implementation("org.llm4s:llm4s-ollama_3:0.5.1")   // the provider you call
}

llm4s-kotlin-api 0.5.1 is not on Maven Central: a release workflow fault left it out of the 0.5.0 and 0.5.1 releases. Until a release includes it, build it locally as the installation guide describes.

Each provider has a builder block, and every call is a suspend function:

1
2
3
4
5
6
7
import org.llm4s.kotlin.Llm4s

suspend fun ask(ollamaUrl: String): String =
    Llm4s.ollama {
        model = "llama3.2"
        baseUrl = ollamaUrl
    }.use { client -> client.complete("What is 2 + 2?") }

A failure is thrown as LLMException. The Kotlin DSL for tools, completion options and agents is in the Java guide’s Kotlin section. The Kotlin API is Experimental.

Spring Boot, Quarkus and the rest

Every code block on this page is compiled and run in CI: the Java is HelloLlm4s.java, run by JavaGuideSpec, and the Kotlin is in WrapClientTest.kt, run against a local stand-in for Ollama.