#1897 Add Kotlin dependencies, plugins, and extensions (#2197)

## Issue
Discussion #1897

## Change
Porting
[kpavlov/langchain4j-kotlin](https://github.com/kpavlov/langchain4j-kotlin)

Integrated Kotlin support by adding necessary dependencies and plugins
to the project. Introduced Kotlin extensions for ChatLanguageModel with
corresponding tests. Updated .editorconfig for improved import and
properties formatting.

- Kotlin dependencies added as optional, so it will not pollute java
projects
- Maven Javadoc plugin replaced with
[Dokka](https://kotlinlang.org/docs/dokka-maven.html) in core module in
order to include both Java and Kotlin docs
- Upgrade Kotlin to
[2.1.0](https://blog.jetbrains.com/kotlin/2024/11/kotlin-2-1-0-released/)

## General checklist
- [x] There are no breaking changes
- [x] I have added unit and integration tests for my change
- [ ] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [ ] I have manually run all the unit and integration tests in the
[core](https://github.com/langchain4j/langchain4j/tree/main/langchain4j-core)
and
[main](https://github.com/langchain4j/langchain4j/tree/main/langchain4j)
modules, and they are all green
- [x] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
This commit is contained in:
Konstantin Pavlov
2024-11-28 12:53:15 +02:00
committed by GitHub
parent cafeb93d6c
commit 2a058796d1
10 changed files with 397 additions and 22 deletions
+14 -14
View File
@@ -116,7 +116,7 @@ ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
ij_java_generate_use_type_annotation_before_type = true
ij_java_if_brace_force = never
ij_java_imports_layout = *,|,javax.**,java.**,|,$*
ij_java_imports_layout = *, |, javax.**, java.**, |, $*
ij_java_indent_case_from_switch = true
ij_java_insert_inner_class_imports = false
ij_java_insert_override_annotation = true
@@ -158,7 +158,7 @@ ij_java_new_line_after_lparen_in_annotation = false
ij_java_new_line_after_lparen_in_deconstruction_pattern = true
ij_java_new_line_after_lparen_in_record_header = false
ij_java_new_line_when_body_is_presented = false
ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
ij_java_packages_to_use_import_on_demand = java.awt.*, javax.swing.*
ij_java_parameter_annotation_wrap = off
ij_java_parameter_name_prefix =
ij_java_parameter_name_suffix =
@@ -318,7 +318,7 @@ ij_less_keep_indents_on_empty_lines = false
ij_less_keep_single_line_blocks = false
ij_less_line_comment_add_space = false
ij_less_line_comment_at_first_column = false
ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
ij_less_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_less_space_after_colon = true
ij_less_space_before_opening_brace = true
ij_less_use_double_quotes = true
@@ -340,7 +340,7 @@ ij_sass_keep_indents_on_empty_lines = false
ij_sass_keep_single_line_blocks = false
ij_sass_line_comment_add_space = false
ij_sass_line_comment_at_first_column = false
ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_sass_space_after_colon = true
ij_sass_space_before_opening_brace = true
ij_sass_use_double_quotes = true
@@ -363,7 +363,7 @@ ij_scss_keep_indents_on_empty_lines = false
ij_scss_keep_single_line_blocks = false
ij_scss_line_comment_add_space = false
ij_scss_line_comment_at_first_column = false
ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_scss_space_after_colon = true
ij_scss_space_before_opening_brace = true
ij_scss_use_double_quotes = true
@@ -417,7 +417,7 @@ ij_typescript_array_initializer_wrap = off
ij_typescript_assignment_wrap = off
ij_typescript_binary_operation_sign_on_next_line = false
ij_typescript_binary_operation_wrap = off
ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_typescript_blank_lines_after_imports = 1
ij_typescript_blank_lines_around_class = 1
ij_typescript_blank_lines_around_field = 0
@@ -601,7 +601,7 @@ ij_javascript_array_initializer_wrap = off
ij_javascript_assignment_wrap = off
ij_javascript_binary_operation_sign_on_next_line = false
ij_javascript_binary_operation_wrap = off
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_javascript_blank_lines_after_imports = 1
ij_javascript_blank_lines_around_class = 1
ij_javascript_blank_lines_around_field = 0
@@ -770,23 +770,23 @@ ij_json_spaces_within_brackets = false
ij_json_wrap_long_lines = false
[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
ij_html_align_attributes = true
ij_html_align_text = false
ij_html_attribute_wrap = normal
ij_html_block_comment_add_space = false
ij_html_block_comment_at_first_column = true
ij_html_do_not_align_children_of_min_lines = 0
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p
ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
ij_html_enforce_quotes = false
ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
ij_html_keep_blank_lines = 2
ij_html_keep_indents_on_empty_lines = false
ij_html_keep_line_breaks = true
ij_html_keep_line_breaks_in_text = true
ij_html_keep_whitespaces = false
ij_html_keep_whitespaces_inside = span,pre,textarea
ij_html_keep_whitespaces_inside = span, pre, textarea
ij_html_line_comment_at_first_column = true
ij_html_new_line_after_last_attribute = never
ij_html_new_line_before_first_attribute = never
@@ -840,7 +840,7 @@ ij_kotlin_field_annotation_wrap = split_into_lines
ij_kotlin_finally_on_new_line = false
ij_kotlin_if_rparen_on_new_line = true
ij_kotlin_import_nested_classes = false
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^
ij_kotlin_indent_before_arrow_on_new_line = true
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
ij_kotlin_keep_blank_lines_before_right_brace = 2
@@ -861,7 +861,7 @@ ij_kotlin_method_parameters_right_paren_on_new_line = true
ij_kotlin_method_parameters_wrap = on_every_item
ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.**
ij_kotlin_packages_to_use_import_on_demand = unset
ij_kotlin_parameter_annotation_wrap = off
ij_kotlin_space_after_comma = true
ij_kotlin_space_after_extend_colon = true
+2
View File
@@ -1 +1,3 @@
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.io=ALL-UNNAMED
-Djava.awt.headless=true
+8
View File
@@ -0,0 +1,8 @@
style:
active: true
MethodName:
active: true
ignoreOverriddenFunctions: true
excludeAnnotatedMethodsOrClasses:
- "org.junit.jupiter.api.Test"
ignoreTestFiles: true
+1
View File
@@ -74,6 +74,7 @@ For easier integration, LangChain4j also includes integration with
- Customization of each step in the RAG flow
- Text classification
- Tools for tokenization and estimation of token counts
- [Kotlin Extensions](/tutorials/kotlin): Asynchronous non-blocking handling of chat interactions using Kotlin's coroutine capabilities.
## 2 levels of abstraction
LangChain4j operates on two levels of abstraction:
@@ -78,7 +78,7 @@ Usually, you, as a developer, should define the content of this message.
Normally, you would write here instructions on what the LLM's role is in this conversation,
how it should behave, in what style to answer, etc.
LLMs are trained to pay more attention to `SystemMessage` than to other types of messages,
so be careful and it's better not to give an end user free access to define or inject some input into a `SystemMessage`.
so be careful, and it's better not to give an end user free access to define or inject some input into a `SystemMessage`.
Usually, it is located at the start of the conversation.
Now that we know all types of `ChatMessage`, let's see how we can combine them in the conversation.
@@ -177,3 +177,7 @@ See more details [here](https://platform.openai.com/docs/guides/vision#low-or-hi
#### PDF File Content
`PdfFileContent` is similar to the `ImageContent`, but represents binary contents of a PDF file.
### Kotlin Extensions
The `ChatLanguageModel` [Kotlin extensions](https://github.com/langchain4j/langchain4j/blob/main/langchain4j-core/src/main/kotlin/dev/langchain4j/model/chat/ChatLanguageModelExtensions.kt) provide asynchronous methods for handling chat interactions with a language model, utilizing Kotlin's [coroutine](https://kotlinlang.org/docs/coroutines-guide.html) capabilities. The `chatAsync` methods allow non-blocking processing of `ChatRequest` or `ChatRequest.Builder` configurations, returning `ChatResponse` with the model's reply. Similarly, `generateAsync` handles the asynchronous generation of responses from chat messages. These extensions simplify building chat requests and handling conversations efficiently in Kotlin applications. Note that these methods are marked as experimental and may evolve over time.
+32
View File
@@ -0,0 +1,32 @@
---
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) to enhance Java APIs with Kotlin-specific conveniences. This allows users to extend existing Java classes with additional functionality tailored for Kotlin.
For instance, Kotlin extensions can convert a [`ChatLanguageModel`](https://docs.langchain4j.dev/tutorials/chat-and-language-models) response into [Kotlin Suspending Function](https://kotlinlang.org/docs/coroutines-basics.html) response into a [Kotlin Suspending Function](https://kotlinlang.org/docs/coroutines-basics.html):
```kotlin
val model = OpenAiChatModel.builder()
.apiKey("your-api-key")
// more configuration parameters here ...
.build()
CoroutineScope(Dispatchers.IO).launch {
val response = model.chatAsync(
ChatRequest.builder()
.messages(
listOf(
SystemMessage.from("You are a helpful assistant"),
UserMessage.from("Hello!")
)
)
)
println(response.aiMessage().text())
}
```
LangChain4j does not require Kotlin libraries as runtime dependencies but allows users to leverage Kotlin's coroutine capabilities for non-blocking execution, enhancing performance and efficiency.
+86 -6
View File
@@ -34,10 +34,21 @@
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core-jvm</artifactId>
<optional>true</optional>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
@@ -55,13 +66,19 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<groupId>org.mockito.kotlin</groupId>
<artifactId>mockito-kotlin</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.willowtreeapps.assertk</groupId>
<artifactId>assertk</artifactId>
<scope>test</scope>
</dependency>
@@ -71,6 +88,12 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-impl</artifactId>
@@ -98,10 +121,67 @@
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>src/test/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.ozsie</groupId>
<artifactId>detekt-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.dokka</groupId>
<artifactId>dokka-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>javadocJar</goal>
<goal>javadoc</goal>
</goals>
<phase>package</phase>
<configuration>
<attach>true</attach>
<outputDir>target/apidocs</outputDir>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<id>prepare-agent</id>
@@ -197,7 +277,7 @@
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -0,0 +1,118 @@
package dev.langchain4j.model.chat
import dev.langchain4j.Experimental
import dev.langchain4j.data.message.AiMessage
import dev.langchain4j.data.message.ChatMessage
import dev.langchain4j.model.chat.request.ChatRequest
import dev.langchain4j.model.chat.response.ChatResponse
import dev.langchain4j.model.output.Response
import kotlinx.coroutines.coroutineScope
/**
* Asynchronously processes a chat request using the language model within
* a coroutine scope. This extension function provides a structured
* concurrency wrapper around the synchronous [ChatLanguageModel.chat] method.
*
* Example usage:
* ```kotlin
* val response = model.chatAsync(ChatRequest(messages))
* ```
*
* @param request The chat request containing messages and optional parameters
* for the model.
* @return [ChatResponse] containing the model's response and any additional
* metadata.
* @throws Exception if the chat request fails or is interrupted.
* @see ChatLanguageModel.chat
* @see ChatRequest
* @see ChatResponse
*/
@Experimental
suspend fun ChatLanguageModel.chatAsync(request: ChatRequest): ChatResponse {
val model = this
return coroutineScope { model.chat(request) }
}
/**
* Asynchronously processes a chat request using a [ChatRequest.Builder] for
* convenient request configuration. This extension function combines the
* builder pattern with coroutine-based asynchronous execution.
*
* Example usage:
* ```kotlin
* val response = model.chatAsync(ChatRequest.builder()
* .messages(listOf(UserMessage("Hello")))
* .temperature(0.7)
* .maxTokens(100))
* ```
*
* @param requestBuilder The builder instance configured with desired chat
* request parameters.
* @return [ChatResponse] containing the model's response and any additional
* metadata.
* @throws Exception if the chat request fails, is interrupted, or the builder
* produces an invalid configuration.
* @see ChatRequest
* @see ChatResponse
* @see ChatRequest.Builder
* @see chatAsync
*/
@Experimental
suspend fun ChatLanguageModel.chatAsync(requestBuilder: ChatRequest.Builder): ChatResponse =
chatAsync(requestBuilder.build())
/**
* Processes a chat request using a [ChatRequest.Builder] for convenient request
* configuration. This extension function provides a builder pattern alternative
* to creating [ChatRequest] directly.
*
* Example usage:
* ```kotlin
* val response = model.chat(ChatRequest.builder()
* .messages(listOf(UserMessage("Hello")))
* .temperature(0.7)
* .maxTokens(100))
* ```
*
* @param requestBuilder The builder instance configured with desired chat
* request parameters.
* @return [ChatResponse] containing the model's response and any additional
* metadata.
* @throws Exception if the chat request fails or the builder produces an
* invalid configuration.
* @see ChatRequest
* @see ChatResponse
* @see ChatRequest.Builder
*/
@Experimental
fun ChatLanguageModel.chat(requestBuilder: ChatRequest.Builder): ChatResponse =
this.chat(requestBuilder.build())
/**
* Asynchronously generates a response for a list of chat messages using
* the language model within a coroutine scope. This extension function
* provides a structured concurrency wrapper around the synchronous
* [ChatLanguageModel.generate] method.
*
* Example usage:
* ```kotlin
* val response = model.generateAsync(listOf(
* SystemMessage("You are a helpful assistant"),
* UserMessage("Hello!")
* ))
* ```
*
* @param messages The list of chat messages representing the conversation
* history and current prompt.
* @return [Response] containing the AI's message and any additional metadata.
* @throws Exception if the generation fails or is interrupted.
* @see ChatLanguageModel.generate
* @see ChatMessage
* @see Response
* @see AiMessage
*/
@Experimental
suspend fun ChatLanguageModel.generateAsync(messages: List<ChatMessage>): Response<AiMessage> {
val model = this
return coroutineScope { model.generate(messages) }
}
@@ -0,0 +1,64 @@
package dev.langchain4j.model.chat
import dev.langchain4j.data.message.AiMessage
import dev.langchain4j.data.message.ChatMessage
import dev.langchain4j.model.chat.request.ChatRequest
import dev.langchain4j.model.chat.response.ChatResponse
import dev.langchain4j.model.output.Response
import kotlinx.coroutines.test.runTest
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.whenever
@ExtendWith(MockitoExtension::class)
internal class ChatLanguageModelExtensionsTest {
@Mock
private lateinit var chatLanguageModel: ChatLanguageModel
@Mock
private lateinit var chatResponse: ChatResponse
@Mock
private lateinit var chatRequest: ChatRequest
@Mock
private lateinit var chatRequestBuilder: ChatRequest.Builder
@Mock
private lateinit var aiMessage: AiMessage
@Test
fun `chatAsync with ChatRequest should return ChatResponse`() = runTest {
whenever(chatLanguageModel.chat(chatRequest)).thenReturn(chatResponse)
val response = chatLanguageModel.chatAsync(chatRequest)
assertThat(response).isEqualTo(chatResponse)
}
@Test
fun `chatAsync with ChatRequest Builder should return ChatResponse`() = runTest {
whenever(chatRequestBuilder.build()).thenReturn(chatRequest)
whenever(chatLanguageModel.chat(chatRequest)).thenReturn(chatResponse)
val response = chatLanguageModel.chatAsync(chatRequestBuilder)
assertThat(response).isEqualTo(chatResponse)
}
@Test
fun `generateAsync should return Response of AiMessage`() = runTest {
val messages = listOf<ChatMessage>()
whenever(chatLanguageModel.generate(messages)).thenReturn(Response(aiMessage))
val response = chatLanguageModel.generateAsync(messages)
assertThat(response.content()).isSameAs(aiMessage)
}
}
+67 -1
View File
@@ -15,6 +15,8 @@
<properties>
<java.version>17</java.version>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.jvmTarget>${java.version}</kotlin.compiler.jvmTarget>
<maven.compiler.release>${java.version}</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputTimestamp>1714382357</project.build.outputTimestamp>
@@ -37,7 +39,9 @@
<testcontainers.version>1.20.3</testcontainers.version>
<bytebuddy.version>1.15.10</bytebuddy.version>
<mockito.version>5.14.1</mockito.version>
<mockito-kotlin.version>5.4.0</mockito-kotlin.version>
<assertj.version>3.24.2</assertj.version>
<assertk.version>0.28.1</assertk.version>
<tinylog.version>2.6.2</tinylog.version>
<httpclient5.version>5.2.1</httpclient5.version>
<opensearch-java.version>2.9.0</opensearch-java.version>
@@ -54,7 +58,8 @@
<awaitility.version>4.2.2</awaitility.version>
<jsonpath.version>2.9.0</jsonpath.version>
<infinispan.version>15.0.0.Final</infinispan.version>
<kotlin.version>2.0.21</kotlin.version>
<kotlin.version>2.1.0</kotlin.version>
<kotlinx.version>1.9.0</kotlinx.version>
</properties>
<dependencyManagement>
@@ -156,6 +161,20 @@
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core-jvm</artifactId>
<optional>true</optional>
<version>${kotlinx.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-test</artifactId>
<version>${kotlinx.version}</version>
<scope>test</scope>
</dependency>
<!-- DEPENDENCY CONFLICT RESOLUTION FOR OKHTTP (END) -->
<dependency>
@@ -217,6 +236,12 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mockito.kotlin</groupId>
<artifactId>mockito-kotlin</artifactId>
<version>${mockito-kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
@@ -228,6 +253,14 @@
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.willowtreeapps.assertk</groupId>
<artifactId>assertk</artifactId>
<version>${assertk.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -429,6 +462,39 @@
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration>
<jvmTarget>${java.version}</jvmTarget>
<javaParameters>true</javaParameters>
<args>
<arg>-Xjsr305=strict</arg>
<arg>-Xjspecify-annotations=strict</arg>
<arg>-Xtype-enhancement-improvements-strict-mode</arg>
</args>
</configuration>
</plugin>
<plugin>
<groupId>org.jetbrains.dokka</groupId>
<artifactId>dokka-maven-plugin</artifactId>
<version>1.9.20</version>
<configuration>
<jdkVersion>${java.version}</jdkVersion>
<languageVersion>2.0</languageVersion>
</configuration>
</plugin>
<plugin>
<groupId>com.github.ozsie</groupId>
<artifactId>detekt-maven-plugin</artifactId>
<version>1.23.7</version>
</plugin>
</plugins>
</pluginManagement>