---
sidebar_position: 29
---

# Kotlin Support

[Kotlin](https://kotlinlang.org) is a statically-typed language targeting the JVM (and other platforms), enabling concise and elegant code with seamless [interoperability](https://kotlinlang.org/docs/reference/java-interop.html) with Java libraries.
LangChain4j utilizes Kotlin [extensions](https://kotlinlang.org/docs/extensions.html) and [type-safe builders](https://kotlinlang.org/docs/type-safe-builders.html) to enhance Java APIs with Kotlin-specific conveniences. This allows users to extend existing Java classes with additional functionality tailored for Kotlin.
    
## Getting Started

Add `langchain4j-kotlin` module to your project dependencies:
```xml
 <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-kotlin</artifactId>
    <version>[LATEST_VERSION]</version>
</dependency>
```

If you want to use data classes, make sure you have [Jackson module kotlin](https://github.com/FasterXML/jackson-module-kotlin) in your classpath. For Maven, add a runtime dependency:

```xml
 <dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-kotlin</artifactId>
    <version>[LATEST_VERSION]</version>
    <scope>runtime</scope>
</dependency>
```

## ChatModel Extensions

This Kotlin code demonstrates how to use [coroutines and suspend functions](https://kotlinlang.org/docs/coroutines-basics.html) and [type-safe builders](https://kotlinlang.org/docs/type-safe-builders.html) to interact with a [`ChatModel`](https://docs.langchain4j.dev/tutorials/chat-and-language-models) in LangChain4j.

```kotlin
val model = OpenAiChatModel.builder()
    .apiKey("YOUR_API_KEY")
    // more configuration parameters here ...
    .build()

CoroutineScope(Dispatchers.IO).launch {
    val response = model.chat {
        messages += systemMessage("You are a helpful assistant")
        messages += userMessage("Hello!")
        parameters {
            temperature = 0.7
        }
    }
    println(response.aiMessage().text())
}
```

The interaction happens asynchronously using Kotlin's **coroutines**:
- `CoroutineScope(Dispatchers.IO).launch`: Executes the process on the [IO dispatcher](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-i-o.html), optimized for blocking tasks like network or file I/O. This ensures responsiveness by preventing the calling thread from being blocked.
- `model.chat` is a suspend function, that uses a builder block to structure the chat request. This approach reduces boilerplate and makes the code more readable and maintainable.

For advanced scenarios, to support custom `ChatRequestParameters`, type-safe builder function accepts custom builder:
```kotlin
fun <B : DefaultChatRequestParameters.Builder<*>> parameters(
    builder: B = DefaultChatRequestParameters.builder() as B,
    configurer: ChatRequestParametersBuilder<B>.() -> Unit
)
```
Example usage:
```kotlin
 model.chat {
    messages += systemMessage("You are a helpful assistant")
    messages += userMessage("Hello!")
    parameters(OpenAiChatRequestParameters.builder()) {
        temperature = 0.7 // DefaultChatRequestParameters.Builder property
        builder.seed(42) // OpenAiChatRequestParameters.Builder property
    }
}
```

## Streaming Use Case

The `StreamingChatModel` extensions provide functionality for use cases where responses need to be processed incrementally as they are generated by the AI model. This is particularly useful in applications requiring real-time feedback, such as chat interfaces, live editors, or systems with streaming token-by-token interaction.
Using Kotlin coroutines, the `chatFlow` extension function converts a streaming response from the language model into a structured and cancellable `Flow` sequence, enabling a coroutine-friendly, non-blocking implementation.


Here’s how you can implement a complete interaction with `chatFlow`:
```kotlin
val flow = model.chatFlow { // similar to non-streaming scenario
    messages += userMessage("Can you explain how streaming works?")
    parameters { // ChatRequestParameters
        temperature = 0.7
        maxOutputTokens = 42
    }
}

runBlocking { // must run in a coroutine context 
    flow.collect { reply ->
        when (reply) {
            is StreamingChatModelReply.PartialResponse -> {
                print(reply.partialResponse) // Stream output as it arrives
            }
            is StreamingChatModelReply.CompleteResponse -> {
                println("\nComplete: ${reply.response.aiMessage().text()}")
            }
            is StreamingChatModelReply.Error -> {
                println("Error occurred: ${reply.cause.message}")
            }
        }
    }
}
```

Check out [this test](https://github.com/langchain4j/langchain4j/blob/main/langchain4j-kotlin/src/test/kotlin/dev/langchain4j/kotlin/model/chat/StreamingChatModelExtensionsKtTest.kt) as an example.

## Compiler Compatibility

When defining tools in Kotlin, ensure that Kotlin compilation is configured to preserve metadata for Java reflection on method parameters by setting [`javaParameters`](https://kotlinlang.org/docs/gradle-compiler-options.html#attributes-specific-to-jvm) to `true`. This setting is required to maintain correct argument names in the tool specification.

When using Gradle, this can be achieved with the following configuration:
```kotlin
kotlin {
    compilerOptions {
        javaParameters = true
    }
}
```
