Commit Graph

11 Commits

Author SHA1 Message Date
Benamira05 cfd90e52f3
fix: Avoid StringIndexOutOfBoundsException when cleaning unclosed code fence in SqlDatabaseContentRetriever (#5737)
## Issue
Closes #5736

## Change

`SqlDatabaseContentRetriever.clean()` strips a markdown code fence from
the generated SQL before executing it. When the response has an opening
fence (```sql```/``````) but no closing fence, `substring(start,
lastIndexOf("```"))` gets `end < start` (`lastIndexOf` matches the
opening fence's own backticks) and throws
`StringIndexOutOfBoundsException`. `clean()` runs outside `retrieve()`'s
`try/catch`, so the exception escapes the retry / `emptyList()` fallback
the method is designed around.

This extracts the shared boundary logic into a `stripCodeFence` helper:
it slices to the closing fence only when one follows the opening tag,
otherwise returns the text after the opening tag. Behaviour for
correctly closed fences is unchanged.

Same underlying bug as #5731, fixed for `HibernateContentRetriever` in
#5732 (both classes independently implement the same fence-stripping
logic; `SqlDatabaseContentRetriever` was missed in that fix).

Added `SqlDatabaseContentRetrieverTest` (the module's first unit test —
`clean()` is `protected` and pure, so no live database is needed)
covering closed fences (regression), unclosed fences for both fence
types, and plain text.

## General checklist
- [X] There are no breaking changes (API, behaviour)
- [X] I have added unit and/or integration tests for my change
- [X] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green

---------

Co-authored-by: Benamira05 <145583236+Benamira05@users.noreply.github.com>
2026-07-09 09:42:59 +02:00
Dmytro Liubarskyi 1f38b0df0b ITs: added missing @EnabledIfEnvironmentVariable annotations 2025-11-24 17:52:11 +01:00
Dmytro Liubarskyi 7b1fdaf5ce fixed failing IT 2025-07-17 10:08:26 +02:00
Dmytro Liubarskyi e19aceaf96
Fix #2918 (#2919)
## Issue
Fixes https://github.com/langchain4j/langchain4j/issues/2918

## Change
- Changed `maxRetry` parameter semantics from "max attempts" to "max
retries".
- Changed default value of the `maxRetry` parameter from 3 to 2, but it
does not change the default behaviour. When `maxRetries` parameter is
not specified explicitly, it will attempt to execute up to 3 times (as
it was before).

## Breaking Change

If you do **_not_** specify `maxRetries` parameter explicitly, there is
no breaking change and you do not need to do any changes to your code.

If you specify `maxRetries` parameter explicitly, you will need to
reduce it by 1, example:
```java
// before
OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName(GPT_4_O_MINI)
            .maxRetries(1)
            .build();

// after
OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName(GPT_4_O_MINI)
            .maxRetries(0)
            .build();
```

## General checklist
- [ ] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] 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)
2025-04-24 16:48:38 +02:00
Dmytro Liubarskyi 13ad410fe8
Rename ChatLanguageModel into ChatModel and StreamingChatLanguageModel into StreamingChatModel (#2866)
## Change
Renamed `ChatLanguageModel` into `ChatModel` and
`StreamingChatLanguageModel` into `StreamingChatModel`.
All `chatLanguageModel(...)` methods were renamed into `chatModel(...)`,
all `streamingChatLanguageModel(...)` methods were renamed into
`streamingChatModel(...)`.

`DisabledChatLanguageModel` was renamed into `DisabledChatModel`,
`DisabledStreamingChatLanguageModel` into `DisabledStreamingChatModel`.

### OpenRewrite recipe:
```yml
---
type: specs.openrewrite.org/v1beta/recipe
name: dev.langchain4j.RenameChatModels
recipeList:
  - org.openrewrite.java.ChangeType:
      oldFullyQualifiedTypeName: dev.langchain4j.model.chat.ChatLanguageModel
      newFullyQualifiedTypeName: dev.langchain4j.model.chat.ChatModel
  - org.openrewrite.java.ChangeType:
      oldFullyQualifiedTypeName: dev.langchain4j.model.chat.StreamingChatLanguageModel
      newFullyQualifiedTypeName: dev.langchain4j.model.chat.StreamingChatModel
  - org.openrewrite.java.ChangeType:
      oldFullyQualifiedTypeName: dev.langchain4j.model.chat.DisabledChatLanguageModel
      newFullyQualifiedTypeName: dev.langchain4j.model.chat.DisabledChatModel
  - org.openrewrite.java.ChangeType:
      oldFullyQualifiedTypeName: dev.langchain4j.model.chat.DisabledStreamingChatLanguageModel
      newFullyQualifiedTypeName: dev.langchain4j.model.chat.DisabledStreamingChatModel
  - org.openrewrite.java.ChangeMethodName:
      methodPattern: dev.langchain4j..* chatLanguageModel(..)
      newMethodName: chatModel
  - org.openrewrite.java.ChangeMethodName:
      methodPattern: dev.langchain4j..* streamingChatLanguageModel(..)
      newMethodName: streamingChatModel
```


## General checklist
- [ ] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [x] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [x] 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)
- [x] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
2025-04-15 10:38:49 +02:00
Mario Fusco a6927bae6e
Delombok (#2751)
Delombok (almost) all.
2025-03-21 17:22:13 +01:00
Dmytro Liubarskyi bebfab832d
Remove old ChatLanguageModel.generate() API (#2621)
## Change
Removed old `ChatLanguageModel.generate()` API.

The `generate()` API was deprecated in previous releases, now we are
removing it to keep only the new `chat()` API.

## General checklist
- [ ] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] 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)
- [x] I have updated [examples
repo](https://github.com/langchain4j/langchain4j-examples):
3ea374bf64
- [X] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring):
https://github.com/langchain4j/langchain4j-spring/pull/117
2025-02-28 13:48:43 +01:00
Dmytro Liubarskyi f1a41b2381
OpenAI: migrate to HttpClient (#2529)
## Issue
Closes #2468


## Changes
1. This PR is a continuation of efforts started in
https://github.com/langchain4j/langchain4j/pull/2413
2. When using `langchain4j-open-ai`, all `OpenAi*Model`s are now using
`java.net.http.HttpClient` instead of OkHttp/Retrofit by default. You
also have an option to [customize it or plug in any other HTTP
client](https://docs.langchain4j.dev/tutorials/customizable-http-client).
3. When using `langchain4j-open-ai-spring-boot-starter`, all
`OpenAi*Model`s are now using Spring's `RestClient` instead of
OkHttp/Retrofit by default. You also have an option to [customize it or
plug in any other HTTP
client](https://docs.langchain4j.dev/tutorials/customizable-http-client).
4. `apiKey` is now optional for all `OpenAi*Model`s
5. `OpenAi*Model`s can now throw
`dev.langchain4j.exception.HttpException` instead of
`dev.ai4j.openai4j.OpenAiHttpException`
6. The default connect timeout is now 15 seconds instead of 60 for all
`OpenAi*Model`s. The default read timeout stays the same (60 seconds).
7. To continue using the "demo" key, you now need to specify the
`baseUrl` explicitly:
```java
OpenAiChatModel model = OpenAiChatModel.builder()
        .baseUrl("http://langchain4j.dev/demo/openai/v1")
        .apiKey("demo")
        .build()
```
8. If you are using `Proxy`, now you need to configure it directly on
the HTTP client of your choice. For example, when using JDK's
`HttpClient`:
```java
HttpClient.Builder httpClientBuilder = HttpClient.newBuilder()
        .proxy(ProxySelector.of(new InetSocketAddress("XXX.XXX.XXX.XXX", 1234)));

OpenAiChatModel model = OpenAiChatModel.builder()
        .httpClientBuilder(JdkHttpClient.builder().httpClientBuilder(httpClientBuilder))
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-4o-mini")
        .build();
```
This also means that all `langchain4j.open-ai.*-model.proxy.*` Spring
Boot properties are not working any more.
9. `OpenAiEmbeddingModel`: removed default `modelName`
(`TEXT_EMBEDDING_ADA_002`), please set it explicitly now
10. `OpenAiImageModel`: removed `withPersisting` and `persistTo`
properties. Persisting images will not be supported any more.
11. `OpenAiLanguageModel` and `OpenAiStreamingLanguageModel`: removed
default `modelName` (`GPT_3_5_TURBO_INSTRUCT`) and `temperature`
(`0.7`), please set it explicitly now
12. `OpenAiModerationModel`: removed default `modelName`
(`TEXT_MODERATION_LATEST`), please set it explicitly now
13. All the `OpenAi*Model` constructors are now accepting a builder
object instead of all the properties
14. The `langchain4j-local-ai` module is now also using
`java.net.http.HttpClient` instead of OkHttp/Retrofit as it depends on
the `langchain4j-open-ai` module


## General checklist
- [ ] There are no breaking changes
- [X] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] 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)
- [x] I have added an example in the examples repo:
https://github.com/langchain4j/langchain4j-examples/pull/143
- [x] I have added/updated Spring Boot starter:
https://github.com/langchain4j/langchain4j-spring/pull/113
2025-02-13 14:25:26 +01:00
LangChain4j 76065fff66 fixed failing tests 2024-08-23 16:03:33 +02:00
hongliangzhang07 8eccd34c68
Fix null pointer issue in SqlDatabaseContentRetriever when column value is null (#1161)
This pull request addresses the null pointer exception issue in the
`SqlDatabaseContentRetriever` class that occurs when a certain column
value from a database query is null. The code now includes a check for
null values before attempting to access them.
2024-05-27 17:10:45 +02:00
LangChain4j 504aa173df
Experimental: RAG: SQL database content retriever (#1056)
## Issue
https://github.com/langchain4j/langchain4j/issues/232

## Change
An experimental `SqlDatabaseContentRetriever` has been added.

Simplest usage example:
```java
ContentRetriever contentRetriever = SqlDatabaseContentRetriever.builder()
    .dataSource(dataSource)
    .chatLanguageModel(openAiChatModel)
    .build();
```
In this case SQL dialect and table structure will be determined from the
`DataSource`.

But it can be customized:
```java
ContentRetriever contentRetriever = SqlDatabaseContentRetriever.builder()
    .dataSource(dataSource)
    .sqlDialect("PostgreSQL")
    .databaseStructure(...)
    .promptTemplate(...)
    .chatLanguageModel(openAiChatModel)
    .maxRetries(2)
    .build();
```

See `SqlDatabaseContentRetrieverIT` for a full example.

## General checklist
<!-- Please double-check the following points and mark them like this:
[X] -->
- [X] There are no breaking changes
- [X] I have added unit and integration tests for my change
- [X] I have manually run all the unit and integration tests in the
module I have added/changed, and they are all green
- [X] 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
<!-- Before adding documentation and example(s) (below), please wait
until the PR is reviewed and approved. -->
- [ ] 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)


## Checklist for adding new model integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [X] I have added my new module in the
[BOM](https://github.com/langchain4j/langchain4j/blob/main/langchain4j-bom/pom.xml)
2024-05-21 16:49:02 +02:00