Commit Graph

171 Commits

Author SHA1 Message Date
Bowang 9ec303daa6
fix(mistralai): guard against empty/null choices in MistralAiChatModel.doChat (#5821)
## Issue

`MistralAiChatModel.doChat()` accesses
`mistralAiResponse.getChoices().get(0)` without checking whether
`choices` is null or empty. When the Mistral AI API (or an
OpenAI-compatible server fronted by it, e.g. vLLM/llama.cpp/Ollama in
OpenAI mode) returns a response with no choices — content filtering,
quota or rate-limit errors, malformed responses — this throws a cryptic
`IndexOutOfBoundsException` (empty list) or `NullPointerException`
(null) instead of a clear failure.

This is the same class of issue reported for `OpenAiChatModel` in #4810,
and complements the `content: null` null-guard recently added to
`MistralAiMapper.aiMessageFrom` in #5123. That guard covers *non-empty*
choices whose `message.content` is null; this PR covers the orthogonal
case of *empty/null* choices themselves. No existing issue covers the
empty-choices case for the MistralAI integration.

## Change

`MistralAiChatModel.doChat()` now checks
`isNullOrEmpty(mistralAiResponse.getChoices())` before the choices are
consumed and throws a descriptive `IllegalArgumentException`, mirroring
the guard already applied in `OpenAiChatModel` (see #4810):

```java
if (isNullOrEmpty(mistralAiResponse.getChoices())) {
    throw new IllegalArgumentException("Mistral AI response has no choices");
}
```

`isNullOrEmpty` is the same helper already imported across the codebase.
No public API or behaviour change for well-formed responses; only the
previously-crashing path now throws a clear exception instead.

## Tests

Added `MistralAiChatModelEmptyChoicesTest`, mirroring the existing
`MistralAiChatModelToolCallsTest` /
`MistralAiChatModelReturnThinkingTest` style (uses `MockHttpClient`, no
API key required). Covers:

1.
`should_throw_IllegalArgumentException_when_response_has_empty_choices`
— empty `choices: []` list → `IllegalArgumentException` (previously
`IndexOutOfBoundsException`).
2.
`should_throw_IllegalArgumentException_when_response_has_null_choices` —
`choices` absent (deserializes to `null`) → `IllegalArgumentException`
(previously `NullPointerException`).
3. `should_return_chat_response_when_response_has_choices` — regression
guard: a well-formed single-choice response is still parsed correctly.

## 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

`mvn -pl langchain4j-mistral-ai -am test
-Dtest=MistralAiChatModelEmptyChoicesTest
-Dsurefire.failIfNoSpecifiedTests=false` → `Tests run: 3, Failures: 0,
Errors: 0, Skipped: 0`, BUILD SUCCESS.
- [ ] 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)
2026-07-31 15:49:11 +02:00
Dmytro Liubarskyi 319246b468 fix(mistral-ai): tolerate a plain-string "error" in batch result entries
Mistral returns the failure detail of a batch result line either as a JSON
object or as a bare JSON string. The latter made Jackson fail with
MismatchedInputException while parsing the output/error file, so a single
failed item broke the whole retrieve() call. The error is now normalized
into a map on deserialization, keeping the field type unchanged.
2026-07-31 10:53:55 +02:00
Subhash Polisetti cb93061643
Introduce `MistralAiChatRequestParameters` for per-request overrides (#5852)
## Issue

Closes #5851

## Change
Mistral's provider-specific options (`safePrompt`, `randomSeed`,
`sendThinking`, `returnThinking`) were settable only at build time and
could not be varied per request. This adds
`MistralAiChatRequestParameters extends DefaultChatRequestParameters` so
they can be overridden per `ChatRequest`, on both `MistralAiChatModel`
and `MistralAiStreamingChatModel`.

```java
model.chat(ChatRequest.builder()
        .messages(UserMessage.from("What is the best French cheese?"))
        .parameters(MistralAiChatRequestParameters.builder()
                .safePrompt(true)
                .randomSeed(42)
                .build())
        .build());
```

- Backward compatible: the model builder options keep working and now
populate the default parameters.
- `strictJsonSchema` remains a model-level setting.
- `defaultRequestParameters()` return type is narrowed to
`MistralAiChatRequestParameters` (source- and binary-compatible; two
`revapi.json` entries added).

Tests: `MistralAiChatRequestParametersTest` (build, `EMPTY`,
`overrideWith`/`defaultedBy`, `toBuilder`, `equals`/`hashCode` incl.
cross-type) and `MistralAiChatModelParametersTest` /
`MistralAiStreamingChatModelParametersTest` (per-request options reach
the request body and override the model defaults, for both models). Docs
updated in `docs/docs/integrations/language-models/mistral-ai.md`.

## 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
- [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)
2026-07-27 11:13:30 +02:00
github-actions[bot] a39f132b91 Update versions to 1.19.0-SNAPSHOT and 1.19.0-beta29-SNAPSHOT 2026-07-17 13:42:56 +00:00
github-actions[bot] 66ad5ee6d5 Release versions 1.18.0 and 1.18.0-beta28 2026-07-17 12:34:45 +00:00
Subhash Polisetti 3b94250b58
Add `MistralAiBatchChatModel` for the Mistral Batch API (#5750)
## Issue

Progresses #3916

## Change
Adds `MistralAiBatchChatModel`, an implementation of the core
`BatchChatModel` interface for the
[Mistral Batch API](https://docs.mistral.ai/capabilities/batch/), which
processes many chat requests
asynchronously at 50% of the standard per-token price. It follows the
existing
`GoogleAiGeminiBatchChatModel`, so both providers expose the same
`submit` / `retrieve` / `cancel` /
`list` surface.

Each `ChatRequest` is built through the same path `MistralAiChatModel`
uses (`createMistralAiRequest`),
so per-request parameters (temperature, tools, response format, etc.)
behave identically in a batch and
in a single call. Requests are submitted inline, so no separate file
upload is needed; once a job
completes, its results are downloaded from the `output_file` /
`error_file` and re-sorted back to
submission order using generated `custom_id`s. Mistral's job statuses
map onto the core `BatchState`:

| Mistral status | `BatchState` |
|---|---|
| `QUEUED` | `PENDING` |
| `RUNNING`, `CANCELLATION_REQUESTED` | `RUNNING` |
| `SUCCESS` | `SUCCEEDED` |
| `FAILED` | `FAILED` |
| `TIMEOUT_EXCEEDED` | `EXPIRED` |
| `CANCELLED` | `CANCELLED` |

The batch operations (create / retrieve / cancel / list jobs, and
downloading a result file) are added
to the existing hand-rolled `MistralAiClient`. They are non-abstract
methods that throw
`UnsupportedFeatureException` by default, so existing `MistralAiClient`
implementations keep compiling
and are unaffected. No new dependency is introduced.

Scope:
- Chat requests only.
- One model per job (a Mistral constraint): the model configured on the
batch model applies to every
  request in the batch.
- Inline submission (the documented path for batches under 10,000
requests); the file-upload submission
  path is not included.

Verified with unit tests against a mock HTTP server custom-id ordering,
success/error mapping,
`output_file` + `error_file` merge, the running-state short-circuit (no
results fetched until the job
produces them), status-code failures, and pagination and with a
key-gated integration test
(`MistralAiBatchChatModelIT`) run end-to-end against the live Batch API
(submit → poll to completion →
read results, plus cancel and list).

## 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
and main modules, and they are all green
- [X] I have added/updated the documentation
- [ ] I have added an example in the examples repo (only for "big"
features)
- [ ] I have added/updated Spring Boot starter(s) (if applicable)

---------

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-07-13 11:22:10 +02:00
Dmytro Liubarskyi 8f58d26d53 fix ITs 2026-07-09 09:34:29 +02:00
github-actions[bot] 7d7c3349d7 Update versions to 1.18.0-SNAPSHOT and 1.18.0-beta28-SNAPSHOT 2026-06-26 14:49:40 +00:00
github-actions[bot] 207407aec9 Release versions 1.17.0 and 1.17.0-beta27 2026-06-26 13:13:06 +00:00
Dmytro Liubarskyi 194b864211
Expose unmapped raw streaming events (#5589)
## Issue

  Closes #5116

  ## Change

Adds a new **`onUnmappedRawEvent`** streaming callback that gives
advanced users access to provider streaming events that LangChain4j does
**not** map to one of its typed callbacks — e.g. OpenAI server-tool
lifecycle events (`response.web_search_call.in_progress` / `searching` /
`completed`). This is an escape hatch so power users don't have to fall
back to a provider's native SDK for events we don't model yet.

**API** (both `@Experimental`, `@since 1.17.0`, `default` so nothing
breaks):

- `StreamingChatResponseHandler.onUnmappedRawEvent(Object rawEvent)` —
low-level API
- `TokenStream.onUnmappedRawEvent(Consumer<Object> rawEventHandler)` —
AI Services API

**Semantics — no duplication.** The callback fires **only** for events
that were *not* already delivered via a typed callback
(`onPartialResponse`, `onPartialThinking`, `onPartialToolCall`,
`onCompleteToolCall`, `onCompleteResponse`). So you can consume the
typed callbacks and the raw stream together without seeing the same
event twice. This is enforced by a small internal
`MappingTrackingStreamingChatResponseHandler` that records whether an
event was mapped to a typed callback (`wasMapped()`), and providers emit
the raw event only when it wasn't.

> Naming note: it's called `onUnmappedRawEvent` (not `onRawEvent`) to
leave room for a planned follow-up that also exposes the raw event
behind *mapped* callbacks (e.g. `PartialToolCall.rawEvent()`), giving a
  clean mapped/unmapped split.

  **The concrete `rawEvent` type is provider-specific:**

  | Provider | Raw event type |
  |---|---|
| OpenAI, Anthropic, Google AI Gemini, Mistral, Ollama |
`dev.langchain4j.http.client.sse.ServerSentEvent` |
| OpenAI (official) – Responses API |
`com.openai.models.responses.ResponseStreamEvent` |
| OpenAI (official) – Chat Completions API |
`com.openai.models.chat.completions.ChatCompletionChunk` |
| Amazon Bedrock |
`software.amazon.awssdk.services.bedrockruntime.model.ConverseStreamOutput`
|
  | Google GenAI | `com.google.genai.types.GenerateContentResponse` |

**Providers wired:** OpenAI (Chat Completions + Responses),
OpenAI-official (Chat Completions + Responses), Anthropic, Google AI
Gemini, Google GenAI, Amazon Bedrock, Mistral, Ollama.

**Docs:** added a "Unmapped Raw Events" section to
`response-streaming.md` and the callback to the `TokenStream` example in
`ai-services.md`.

  ## General checklist
- [x] There are no breaking changes (API, behaviour) — all additions are
`default` and `@Experimental`
  - [x] I have added unit and/or integration tests for my change
- [x] The tests cover both positive and negative cases — i.e. unmapped
events are forwarded *and* typed (text/tool) events are **not** repeated
as raw events
- [x] I have manually run all the unit and integration tests in the
module(s) 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)
2026-06-25 21:14:30 +02:00
Eunbin Son f9720a9fe4
fix: Honor strictJsonSchema option in MistralAiStreamingChatModel (#5583)
## Issue
Closes #5582

## Change
`MistralAiStreamingChatModel.doChat()` passed the literal `false` for
the `strict` flag and the builder had no setter, so strict JSON schema
was always disabled for the streaming model, unlike the synchronous
`MistralAiChatModel`. This is an incomplete fix from PR #4603, which
wired the option into the synchronous model only.

This mirrors the synchronous model: a `strictJsonSchema` field
initialized via `getOrDefault(builder.strictJsonSchema, false)`, a
builder field and setter, and the field passed to
`createMistralAiRequest` instead of the hardcoded `false`.

```java
MistralAiChatCompletionRequest request =
        createMistralAiRequest(chatRequest, safePrompt, randomSeed, true, sendThinking, strictJsonSchema);
```

The default stays `false`, so existing callers are unaffected.

Added `MistralAiStreamingChatModelStrictJsonSchemaTest`
(`MockHttpClient`, no API key): a positive test asserts the request body
contains `"strict":true` when `strictJsonSchema(true)` is set, and a
regression test asserts `"strict":false` when it is not.

## 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)

Spotless: jgit ratchet fails inside the worktree ("Cannot find git
repository"), so the two changed files were copied to the main checkout
and `spotless:check -pl langchain4j-mistral-ai` was run there (0 files
needed changes, both already clean); the temporary copies were then
reverted.
2026-06-25 09:58:58 +02:00
Eunbin Son 7c256508b3
fix: Guard against null content in Mistral FIM streaming event listener (#5581)
## Issue
Closes #5580

## Change
`MistralAiFimServerSentEventListener.onEvent()` iterated the content
delta with an enhanced-for loop and no null check. Mistral streams
normal SSE deltas with no `content` field (for example the
`finish_reason` / metadata-only chunk), so
`choice.getDelta().getContent()` is `null` and the loop throws
`NullPointerException`.
This wraps the loop in `if (isNotNullOrEmpty(chunks))`, mirroring the
existing guard in the chat streaming listener
`MistralAiServerSentEventListener` (line 107). `isNotNullOrEmpty` was
already statically imported, so there are no new imports or
dependencies.
Added `MistralAiStreamingFimModelTest` using `MockHttpClient` to inject
SSE without an API key: a negative case feeds a content-less
`finish_reason` delta (NPE before the fix, passes after) and a positive
case asserts text is streamed and concatenated.
This completes PR #5123, which fixed the chat paths but left the FIM
streaming path unguarded.

## 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
- [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)
2026-06-25 09:58:16 +02:00
Dmytro Liubarskyi 7504909832 fixing ITs 2026-06-22 11:22:41 +02:00
Dmytro Liubarskyi 2999c58965 fixing ITs 2026-06-12 10:04:59 +02:00
Dmytro Liubarskyi 1757733c6f fixing ITs 2026-06-09 09:40:21 +02:00
Dmytro Liubarskyi d4008f8764 fixing ITs 2026-06-08 11:44:34 +02:00
github-actions[bot] 01de41d641 Update versions to 1.17.0-SNAPSHOT and 1.17.0-beta27-SNAPSHOT 2026-06-06 06:46:38 +00:00
github-actions[bot] cd836845dd Release versions 1.16.0 and 1.16.0-beta26 2026-06-05 15:46:56 +00:00
Dmytro Liubarskyi b2df847b0f fixing ITs 2026-05-28 17:47:10 +02:00
github-actions[bot] 6185599e37 Update versions to 1.16.0-SNAPSHOT and 1.16.0-beta26-SNAPSHOT 2026-05-15 16:21:14 +00:00
github-actions[bot] d0e54aa006 Release versions 1.15.0 and 1.15.0-beta25 2026-05-15 15:55:12 +00:00
Maxime 45c5fb76e5
fix(mistralai): null-guard MistralAiChatMessage.getContent() in aiMes… (#5123)
<!--
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 #5121.

## Change
<!-- Please describe the changes you made. -->
Minimal, behavior-preserving null-guard in
`MistralAiMapper.aiMessageFrom`. OpenAI-compatible servers (vLLM,
llama.cpp, …) return `content: null` on assistant messages that carry
only `tool_calls`. The current mapper unconditionally calls `.stream()`
on `aiMistralMessage.getContent()`, which NPEs on this spec-compliant
payload.

The fix treats null content as an empty list — both the `text` and
`thinking` extraction streams now operate on the local reference:

```java
List<MistralAiMessageContent> contents = aiMistralMessage.getContent();
if (contents == null) {
    contents = List.of();
}
```

No public API or behaviour change for callers: `text` is still `""` when
there is no text content, `thinking` stays `null` when no thinking
content. No new dependencies. Spotless applied.

Adds `MistralAiChatModelToolCallsTest` mirroring
`MistralAiChatModelReturnThinkingTest` (uses `MockHttpClient`), with
three scenarios:
1. `should_handle_response_with_only_tool_calls_and_null_content` — the
regression case (vLLM-style payload, captured byte-for-byte from a real
production response).
2. `should_handle_response_with_both_text_content_and_tool_calls` —
sanity, both fields present.
3. `should_handle_response_with_text_only_and_no_tool_calls` — ensures
the null-guard doesn't disturb the existing text-only path.


## 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
<!-- Doc/example checkboxes left unchecked: a 3-line internal-mapper
null-guard does not require docs or example updates. Happy to add either
if a maintainer disagrees. -->
- [ ] 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)

 ### Note on the test runs

Ran `mvn -fae clean test` from the repo root and a follow-up `mvn -fae
clean test -pl '!embeddings/langchain4j-embeddings'`. Combined: **59
modules pass cleanly, 2 modules fail, 46 modules auto-skip** as
transitive dependents of the failures.

**Both failures share a single root cause unrelated to this change**:
`ai.djl.engine.EngineException: Failed to load Huggingface native
library` (`Unexpected flavor:
cpu` — DJL HuggingFace native binaries do not load on aarch64 / Apple
Silicon). Affects:
  - `langchain4j-embeddings` directly
- `langchain4j` main module (15 test classes touching
`AllMiniLmL6V2QuantizedEmbeddingModel` static init)
- `langchain4j-azure-ai-search` (`AzureAiSearchContentRetrieverTest`
setup uses the same embedding model)

The module touched by this PR — `langchain4j-mistral-ai` — was tested
independently: **21/21 unit tests green** (3 new + 18 pre-existing). CI
will validate the rest.


## 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: madaram <6826292+madaram@users.noreply.github.com>
Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-05-07 10:36:41 +02:00
github-actions[bot] 628ac34c01 Update versions to 1.15.0-SNAPSHOT and 1.15.0-beta25-SNAPSHOT 2026-04-30 18:43:12 +00:00
github-actions[bot] 4917afa297 Release versions 1.14.0 and 1.14.0-beta24 2026-04-30 18:10:30 +00:00
Diego Berríos b468b0304a
feat: Support `PdfFileContent` for Mistral (#5014)
<!--
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 #5013 

## Change
<!-- Please describe the changes you made. -->
Added support for `PdfFileContent` for the Mistral AI integration, very
similar to https://github.com/langchain4j/langchain4j/pull/4978

- Modified `MistralAiMapper.toMistralAiMessageContents()` so it now
supports mapping `PdfFileContent` to Mistral's API format
(`DocumentURLChunk`).
- Added `MistralAiDocumentUrlContent` and
`MistralAiDocumentBase46Content` classes for modeling
`DocumentUrlChunk`. The API supports both using URLs and base64 strings
for representing the `document_url` field in `DocumentUrlChunk`.
- Added the two classes as well to keep consistency with how image
chunks are handled in the module (`MistralAiImageBase64Content`,
`MistralAiImageUrlContent`, and the audio chunk representations as
well).
- For testing, the URL pdf file is from [Wikimedia
Commons](https://commons.wikimedia.org/wiki/Main_Page) to avoid
copyright issues, and the local one is just one I made up (it only
contains `Bonjour!`).

## 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. -->
- [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)

---------

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-04-24 10:20:30 +02:00
Diego Berríos d5e0c923c4
feat: Mistal AI `AudioContent` support (#4978)
<!--
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 #4977 

## Change
<!-- Please describe the changes you made. -->
Added support for `AudioContent` for the Mistral AI integration.

- Modified `MistralAiMapper.toMistralAiMessageContents()`' so it
supports mapping `AudioContent` to Mistral's API format (`AudioChunk`).
- Added `MistralAiAudioBase64Content` and `MistralAiAudioUrlContent`
classes for modeling `AudioChunk`. The API supports both using URLs and
base64 strings for representing the content of an audio chunk
- Added the two classes as well to keep consistency with how image
chunks are handled in the module (`MistralAiImageBase64Content` and `
MistralAiImageUrlContent`).
- Added two more values for `MistralAiChatModelName` for easy access to
Voxtral latest models.
- Tests cover `AudioContent` instances generated from base64 data and
URL.
- Audio files are from [Wikipedia
Commons](https://commons.wikimedia.org/wiki/Main_Page) to avoid
copyright issues :).

## 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. -->
- [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)


## 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
2026-04-21 09:27:59 +02:00
github-actions[bot] 4798a89d66 Update versions to 1.14.0-SNAPSHOT and 1.14.0-beta24-SNAPSHOT 2026-04-09 14:41:27 +00:00
github-actions[bot] 759cd9a236 Release versions 1.13.0 and 1.13.0-beta23 2026-04-09 13:07:30 +00:00
Dmytro Liubarskyi 8ff282f12c
Support Tools Returning Images (#4851)
## Issue
Closes https://github.com/langchain4j/langchain4j/issues/4652

## Change
- Add support for `@Tool`-annotated methods to return multimodal content
(images) to the LLM, not just text. Tools can now return `Image`,
`ImageContent`, `Content`, `List<Content>`, `Content[]`, etc.
- Refactor `ToolExecutionResultMessage` to store `List<Content>`
internally instead of a plain `String`, with backward-compatible
`text()` accessor and new `contents()` / `hasSingleText()`
  methods.
- Refactor `ToolExecutionResult` to support
`resultContents(List<Content>)` as an alternative to
`resultText(String)` and `resultTextSupplier(Supplier)`.
- Implement multimodal tool result mapping for providers that support
it: Anthropic, Amazon Bedrock, and Google AI Gemini.
- Add `UnsupportedFeatureException` guards in providers that do not
support non-text tool results: Azure OpenAI, GitHub Models, Jlama,
Mistral AI, Ollama, OpenAI (Chat Completions
& Responses), Vertex AI (Anthropic & Gemini), Watsonx, and Workers AI.
- Update `ToolExecutedEvent` / `DefaultToolExecutedEvent` to carry
`resultContents` alongside the existing `resultText` accessor.
- Add comprehensive unit and integration tests
(`should_execute_tool_returning_Image`,
`should_execute_tool_returning_ImageContent`,
`should_execute_tool_returning_ContentList`,

`should_fail_when_tool_returns_image_and_provider_does_not_support_it`).
- Update tools documentation with new "Returning Images and Multimodal
Content" and "Multimodal Tool Results" sections.

## 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
- [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)
2026-04-07 13:54:34 +02:00
Jean Bisutti 4f553bd04f
Fix NPE in MistralAiModerationModel when categories is null (#4733)
The NPE was possible before #4695.
2026-03-19 18:25:21 +01:00
Jean Bisutti 1e29fcb867
Refactor moderation models (#4695)
Refactor `OpenAiModerationModel` and `MistralAiModerationModel `to make
them more readable and facilitate the addition of new features.

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-03-18 11:51:55 +01:00
Dmytro Liubarskyi 42089e02a8 fixing flaky tests 2026-03-17 09:49:18 +01:00
Dmytro Liubarskyi e10abf04d0
Update versions to 1.13.0-SNAPSHOT and 1.13.0-beta23-SNAPSHOT (#4710)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-13 11:39:50 +01:00
Dmytro Liubarskyi c92ea033e4
Update versions to 1.13.0-SNAPSHOT and 1.13.0-beta22-SNAPSHOT (#4666)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-05 17:18:22 +01:00
Dmytro Liubarskyi 193ac0d7be Add ModerationModel listener support and ModerationRequest/ModerationResponse API (#4588) 2026-03-03 17:41:06 +01:00
Jean Bisutti d80bfe3f7e
Add ModerationModel listener support and ModerationRequest/ModerationResponse API (#4588)
## Issue

This PR adds observability support for `ModerationModel`
implementations, following the same patterns established for `ChatModel`
listeners. It introduces a new request/response API for moderation
operations and provides listener callbacks for monitoring moderation
requests, responses, and errors.

## Change

Commits:

1)
[f025c0f61](https://github.com/jeanbisutti/langchain4j/commit/f025c0f61)
- **Add ModerationRequest/ModerationResponse API to ModerationModel**
- Introduce `ModerationRequest` with builder pattern supporting both
text and messages
- Introduce `ModerationResponse` with metadata (model name, token usage,
finish reason)
- Add `moderate(ModerationRequest)` method to `ModerationModel`
interface
- Update all implementations (OpenAI, MistralAI, Watsonx) to support the
new API
   - Add unit tests for request/response classes

2)
[aed77bf60](https://github.com/jeanbisutti/langchain4j/commit/aed77bf60)
- **Add moderation model listener support**
- Add `ModerationModelListener` interface with `onRequest`,
`onResponse`, `onError` callbacks
- Add context classes: `ModerationModelRequestContext`,
`ModerationModelResponseContext`, `ModerationModelErrorContext`
- Add `ModerationModelListenerUtils` for consistent listener invocation
across implementations
- Implement listener support in OpenAI, MistralAI, and Watsonx
moderation models
- Add `AbstractModerationModelListenerIT` base test class for consistent
testing
   - Add documentation in observability tutorial

3)
[2c600cd90](https://github.com/jeanbisutti/langchain4j/commit/2c600cd90)
- **Refactoring - Add toInputs and toText utility methods to
ModerationModel**
- Extract common `toInputs()` and `toText()` utility methods to
`ModerationModel` interface
- Remove duplicate code from OpenAI, MistralAI, and Watsonx
implementations

**Backward Compatibility:** The existing `moderate(String text)` and
`moderate(ChatMessage... messages)` methods remain unchanged. The new
`moderate(ModerationRequest)` API is additive. Listener support is
opt-in via builder configuration.


## 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
- [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. -->
- [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)

---------

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-03-03 17:26:36 +01:00
Sascha Woo 332a3a7564
Add strict option for JSON schema response format to Mistral AI (#4603)
## Issue
Closes #4602

## Change
This adds a builder method to the `MistralAiChatModelBuilder` to
configure strict JSON schema for response format, as is done in the
OpenAI implementation.

## 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
- [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. -->
- [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)


## 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>
2026-02-25 18:30:22 +01:00
YannC a9a2b32fdd
feat: add new "customHeaders" property to MistralAiClient (#4569)
<!--
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 #4568

## Change
Added the possibility to have a custom headers, I did as it was done for
Ollama


## 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
<img width="575" height="280" alt="image"
src="https://github.com/user-attachments/assets/563f2f58-0fef-493d-9d1a-9d71f09e5ad9"
/>

- [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

### Once reviewed & approved
<!-- 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)
2026-02-10 15:07:42 +01:00
Dmytro Liubarskyi 336b2accce
Update versions to 1.12.0-SNAPSHOT and 1.12.0-beta20-SNAPSHOT (#4537)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 14:27:44 +01:00
Dmytro Skarzhynets 2327b48c1f
feat: support reasoning models for Mistral AI (#4474)
<!--
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 #4476 

## Change
<!-- Please describe the changes you made. -->
Add support for Mistral AI's Magistral reasoning models.

- Add `MAGISTRAL_SMALL_LATEST` and `MAGISTRAL_MEDIUM_LATEST` model names
- Add `returnThinking` parameter to parse thinking content from API
responses into `AiMessage.thinking()`
- Add `sendThinking` parameter to include thinking content in follow-up
requests for multi-turn conversations
- Support streaming of thinking content via `onPartialThinking` callback

### Response format handling

The Mistral API can return content in two formats. As a simple string:

```json
{
    "message": {
        "role": "assistant",
        "content": "The answer is 42."
    }
}
```

Or as an array of structured blocks when thinking is included:

```json
{
    "message": {
        "role": "assistant",
        "content": [
            {"type": "thinking", "thinking": [{"type": "text", "text": "Let me reason..."}]},
            {"type": "text", "text": "The answer is 42."}
        ]
    }
}
```

I added a custom deserializer handles both formats.

### Testing notes

Tests for `returnThinking` use mocked HTTP responses rather than real
API calls. I was not able to reliably trigger Magistral models to return
thinking content, which would make real API tests flaky.

## References

- [Mistral AI Chat Completions
API](https://docs.mistral.ai/api/#tag/chat/operation/chat_completion_v1_chat_completions_post)
- [Mistral AI Reasoning
doc](https://docs.mistral.ai/capabilities/reasoning)

## 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
- [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>
2026-02-03 13:57:14 +01:00
Fabian N. d5d6219670
MistralAi: return raw HTTP response and SSE events (#4405)
## Issue
Closes #4222

## Change
Similiar to #4225: Exposes raw HTTP Header via
`MistralAiChatResponseMetadata` for MistralAiChatModel by passing
through the data from HTTP client.


## 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
- [ ] 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)
2026-02-03 11:50:02 +01:00
Dmytro Liubarskyi ee36861e93 fixing flaky tests 2026-02-02 09:40:20 +01:00
Dmytro Liubarskyi 6363fdb80a CI: parallelize tests in main module 2026-01-09 11:11:57 +01:00
Dmytro Liubarskyi 778be1b360
Update versions to 1.11.0-SNAPSHOT and 1.11.0-beta19-SNAPSHOT (#4285)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-24 15:38:05 +01:00
Dmytro Liubarskyi a01b84b49e WIP: Feature 3437 model discovery (#4240) 2025-12-24 12:48:15 +01:00
Bernhard Haumacher 770c06baf6
WIP: Feature 3437 model discovery (#4240)
<!--
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 #3437

## Change
<!-- Please describe the changes you made. -->
Allow customers to discover available models and their capabilities
programmatically without visiting provider websites.

Core Infrastructure (langchain4j-core):
- Added ModelDiscovery interface for unified model discovery API
- Added ModelDescription class for standardized model metadata
- Added ModelType enum (CHAT, EMBEDDING, IMAGE_GENERATION, etc.)
- Added ModelDiscoveryFilter for filtering models by type, capabilities,
context window, etc.
- Added ModelPricing class for model pricing information
- Created comprehensive unit tests for all core classes
- Created AbstractModelDiscoveryIT base class for provider integration
tests

OpenAI Implementation (langchain4j-open-ai):
- Extended OpenAiClient with listModels() method for GET /v1/models
endpoint
- Added ModelsListResponse and OpenAiModelInfo API response classes
- Implemented OpenAiModelDiscovery with client-side filtering support
- Follows existing OpenAI builder pattern and conventions

Anthropic Implementation (langchain4j-anthropic):
- Implemented AnthropicModelDiscovery with static model registry
- Includes Claude 3.5 Sonnet, Haiku, Opus and Claude 3 models
- Provides complete pricing and capability metadata
- Supports client-side filtering

Key Features:
- Unified API across all providers
- Flexible filtering by type, capabilities, context window, name pattern
- Builder pattern consistent with existing LangChain4j conventions
- Immutable data structures for thread safety
- No breaking changes to existing APIs
- Comprehensive test coverage


## 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
- [ ] 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)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2025-12-24 12:46:52 +01:00
Dmytro Liubarskyi 25d3b3ec87 cleaned up test dependencies 2025-12-10 10:18:30 +01:00
Dmytro Liubarskyi 36a8d74eaa fixing flaky ITs 2025-12-04 10:08:23 +01:00
Dmytro Liubarskyi ca6097e35d
Update versions to 1.10.0-SNAPSHOT and 1.10.0-beta18-SNAPSHOT (#4152)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-28 12:21:30 +01:00
Dmytro Liubarskyi bc0801a4df
Update versions to 1.10.0-SNAPSHOT and 1.10.0-beta17-SNAPSHOT (#4140)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-26 17:38:36 +01:00