## Change
Migrates the two web search engine modules off Retrofit/OkHttp and onto
LangChain4j's own HttpClient abstraction (dev.langchain4j.http.client),
consistent with the modules already migrated (OpenAI, Anthropic,
Mistral, Gemini, Voyage, etc.). This removes the retrofit, okhttp, and
converter-jackson dependencies from both modules and routes HTTP through
the pluggable, backend-agnostic client (defaulting to the JDK
client at runtime).
langchain4j-web-search-engine-tavily
- TavilyClient now issues a POST via HttpClient instead of a
Retrofit-generated interface; TavilyApi (Retrofit) removed.
- Added TavilyJsonUtils carrying the exact ObjectMapper configuration
the Retrofit converter used (SNAKE_CASE + NON_NULL + lenient
deserialization). This is required because the Tavily DTOs have no
@JsonProperty annotations and relied on Retrofit's snake_case mapper —
the wire format is preserved byte-for-byte.
- pom.xml: replaced retrofit/okhttp/converter-jackson with
langchain4j-http-client (compile) + langchain4j-http-client-jdk
(runtime).
langchain4j-web-search-engine-searchapi
- SearchApiClient now issues a GET with URL-encoded query params and the
Authorization: Bearer header via HttpClient; SearchApi (Retrofit)
removed.
- Added SearchApiJsonUtils (lenient mapper; the response DTOs already
self-annotate with @JsonNaming/@JsonIgnoreProperties).
- Same pom.xml dependency swap as Tavily.
New (additive, non-breaking) public builder options on both engines
- httpClientBuilder(HttpClientBuilder), logRequests(Boolean),
logResponses(Boolean) — bringing these engines in line with other
integrations and enabling custom HTTP client configuration and
request/response
logging. Existing public constructors are retained and delegate to the
new wider ones, so no existing caller breaks.
- Added a revapi.json to each module ignoring
java.class.externalClassExposedInAPI for HttpClientBuilder, matching the
existing convention in langchain4j-chroma, langchain4j-open-ai,
langchain4j-voyage-ai,
etc.
Behavioral note: on non-2xx responses the client now throws
dev.langchain4j.exception.HttpException (a RuntimeException subclass)
instead of a plain RuntimeException with a "status code: …" message —
the same
behavior all other migrated modules already exhibit.
## General checklist
- [x] There are no breaking changes (API, behaviour)
- [ ] 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
- [ ] 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)
## Issue
Closes#5627
## Change
`GoogleCustomWebSearchEngine` aborted the whole search when one result
link could not be parsed into a URI.
`UriUtils.createUriSafely` returns `null` for links that
percent-encoding cannot repair. That `null` reached
`WebSearchOrganicResult.from(...)`, whose constructor calls
`ensureNotNull(url, "url")` and threw `IllegalArgumentException`, which
propagated out of the stream. The image branch had the same problem on
the primary image link.
Both mapping paths now skip a result whose primary link resolves to
`null` and keep the rest. For images, only the primary `imageLink`
triggers a skip; `contextLink` and `thumbnailLink` stay nullable as
before, so their absence does not drop a result.
To make the mapping unit-testable without an API key,
`toWebSearchOrganicResults` is now package-private and the inline
image-mapping lambda is extracted into a package-private
`toImageSearchResults(Search)` helper. Valid links map exactly as
before.
This completes the fix for #3588 (the encoding part was handled in
#3589).
## 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
- [ ] 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
- [ ] 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)
<!-- "new maven module" and "embedding store" checklist sections
omitted: not applicable (no new module, not an embedding store). -->
URLs returned by web search APIs may contain illegal characters (spaces,
pipes, braces, etc.) that cause URI.create() to throw
IllegalArgumentException.
<!--
Thank you so much for your contribution!
Please fill in all the sections below.
Please open the PR as a draft initially. Once it is reviewed and
approved, we will ask you to add documentation and examples.
Please note that PRs with breaking changes or without tests will be
rejected.
Please note that PRs will be reviewed based on the priority of the
issues they address.
We ask for your patience. We are doing our best to review your PR as
quickly as possible.
Please refrain from pinging and asking when it will be reviewed. Thank
you for understanding!
-->
## Issue
<!-- Please specify the ID of the issue this PR is addressing. For
example: "Closes #1234" or "Fixes #1234" -->
Fixes#1540 more thoroughly. The
https://github.com/langchain4j/langchain4j/pull/1541 PR only fixes empty
spaces, but there are other illegal characters that need to be handled.
This PR introduces `UriUtils` intended to be used by all search engines.
## Change
<!-- Please describe the changes you made. -->
## General checklist
<!-- Please double-check the following points and mark them like this:
[X] -->
- [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
- [] 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)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
## Checklist for adding new maven module
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added my new module in the root `pom.xml` and
`langchain4j-bom/pom.xml`
## Checklist for adding new embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreIT` that extends
from either `EmbeddingStoreIT` or `EmbeddingStoreWithFilteringIT`
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreRemovalIT` that
extends from `EmbeddingStoreWithRemovalIT`
## Checklist for changing existing embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
<!--
Thank you so much for your contribution!
Please fill in all the sections below.
Please open the PR as a draft initially. Once it is reviewed and
approved, we will ask you to add documentation and examples.
Please note that PRs with breaking changes or without tests will be
rejected.
Please note that PRs will be reviewed based on the priority of the
issues they address.
We ask for your patience. We are doing our best to review your PR as
quickly as possible.
Please refrain from pinging and asking when it will be reviewed. Thank
you for understanding!
-->
## Issue
<!-- Please specify the ID of the issue this PR is addressing. For
example: "Closes #1234" or "Fixes #1234" -->
Fixes#3588
## Change
This PR fixes URI creation safety by replacing direct URI constructors
with the createUriSafely() utility method to prevent crashes from
malformed URLs returned by Google's API.
Changes Made:
Safe URI creation for image search results (imageLink, contextLink,
thumbnailLink)
Safe URI creation for organic search results
Added static import for createUriSafely utility (introduced in separate
class)
Prevents IllegalArgumentException and applied fallback when Google API
returns invalid URL strings, making the search mapping more robust.
## 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/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
- [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)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
## Checklist for adding new maven module
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added my new module in the root `pom.xml` and
`langchain4j-bom/pom.xml`
## Checklist for adding new embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreIT` that extends
from either `EmbeddingStoreIT` or `EmbeddingStoreWithFilteringIT`
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreRemovalIT` that
extends from `EmbeddingStoreWithRemovalIT`
## Checklist for changing existing embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
---------
Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
<!--
Thank you so much for your contribution!
Please fill in all the sections below.
Please open the PR as a draft initially. Once it is reviewed and
approved, we will ask you to add documentation and examples.
Please note that PRs with breaking changes or without tests will be
rejected.
Please note that PRs will be reviewed based on the priority of the
issues they address.
We ask for your patience. We are doing our best to review your PR as
quickly as possible.
Please refrain from pinging and asking when it will be reviewed. Thank
you for understanding!
-->
## Issue
<!-- Please specify the ID of the issue this PR is addressing. For
example: "Closes #1234" or "Fixes #1234" -->
Closes #
## Change
<!-- Please describe the changes you made. -->
I noticed that in a lot of files there are duplicated checks for `null`
and not empty or `null` and not blank. Since there exist functions in
`Utils` class which do exactly that, I replaced all custom checks with
calls to such functions.
## General checklist
NB: I purposefully didn't commit formatting changes (i.e., `make lint`
and `make format`) because they'd change many lines in many files, much
more than what I changed in this PR, and that'd make PR difficult to
review. If you think I should do it, I'd gladly commit them.
<!-- Please double-check the following points and mark them like this:
[X] -->
- [x] There are no breaking changes
- [ ] I have added unit and/or integration tests for my change
- [ ] The tests cover both positive and negative cases
- [ ] 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
<!-- 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)
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable)
## Checklist for adding new maven module
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added my new module in the root `pom.xml` and
`langchain4j-bom/pom.xml`
## Checklist for adding new embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreIT` that extends
from either `EmbeddingStoreIT` or `EmbeddingStoreWithFilteringIT`
- [ ] I have added a `{NameOfIntegration}EmbeddingStoreRemovalIT` that
extends from `EmbeddingStoreWithRemovalIT`
## Checklist for changing existing embedding store integration
<!-- Please double-check the following points and mark them like this:
[X] -->
- [ ] I have manually verified that the
`{NameOfIntegration}EmbeddingStore` works correctly with the data
persisted using the latest released version of LangChain4j
---------
Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
## Change
- Added `maven-flatten-plugin` to `langchain4j-parent` and
`langchain4j-bom`
- Removed integration-specific dependencies from `langchain4j-parent`'s
`dependencyManagement` section and moved them to the modules where these
dependencies are used
- Explicitly added missing implicit dependencies
- Removed redundant `<maven.compiler.release>` for cassandra, infinispan
and opensearch modules
- Removed redundant license declarations and outdated properties
## 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
- [ ] 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)
## 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)
## 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)