Commit Graph

238 Commits

Author SHA1 Message Date
Subhash Polisetti 56dc9aa882
Add `AnthropicBatchChatModel` for the Anthropic Message Batches API (#5875)
Progresses #3916.

## Change

Adds `AnthropicBatchChatModel`, an implementation of the core
`BatchChatModel` interface
(`submit` / `retrieve` / `cancel` / `list`) for the [Anthropic Message
Batches
API](https://docs.anthropic.com/en/docs/build-with-claude/batch-processing),
which processes many chat requests asynchronously at 50% of the standard
per-token price.

Each request is built through the same `createAnthropicRequest` path as
`AnthropicChatModel`, so per-request
parameters (tools, thinking, caching, etc.) behave identically in a
batch and in a single call. Results come
back in arbitrary order and are re-sorted to submission order by
generated `custom_id`s. Anthropic reports
only `in_progress` / `canceling` / `ended` at the batch level, so
`ended` maps to `BatchState.SUCCEEDED` and
the per-request `succeeded` / `errored` / `canceled` / `expired`
outcomes are surfaced as `BatchItemResult`s.

The batch endpoints are added to the existing hand-rolled
`AnthropicClient` as default methods that throw
`UnsupportedFeatureException`, so existing `AnthropicClient`
implementations keep compiling. No new
dependency. Chat requests only.

Covered by unit tests against a mock HTTP server (custom-id ordering,
success/error/canceled mapping, the
in-progress case that fetches no results until the batch ends, and
pagination). The integration test
`AnthropicBatchChatModelIT` (key-gated on `ANTHROPIC_API_KEY`) was also
run against the live Batches API and
passes, exercising submit / retrieve / list / cancel.

## 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
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-30 11:47:48 +02:00
rain 45b058edf4
fix(anthropic): apply cache_control to image and pdf content blocks (#5868)
## Issue
Closes #5867 

## Change

`AnthropicMapper` only applied `cache_control=ephemeral` to
`TextContent` when a
`UserMessage` was marked for caching, silently dropping it when the last
content
item was `ImageContent` or `PdfFileContent`. This contradicts the
surrounding
code comment ("apply the cache_control to the last content item") and
the
documented behavior in `anthropic.md`.

- Add `cacheControl`-accepting constructors and `from*` overloads to
`AnthropicImageContent` and `AnthropicPdfContent` (mirrors
`AnthropicTextContent`)
- In `AnthropicMapper`, pass `cacheControl` to Image/Pdf content when
`applyCache`
- Include `cacheControl` in `AnthropicPdfContent.toString()` (already
present on
  `AnthropicImageContent` and `AnthropicTextContent`)

Only the user turn is affected, matching Anthropic's prompt caching
restriction.
Nested blocks inside `tool_result` are unchanged — sub-content blocks
cannot be
cached directly. Backward compatible: additive overloads; `cacheControl`
is null
when absent.

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

Co-authored-by: tianyu.zhao <mrzgetbetter820@users.noreply.github.com>
2026-07-30 09:43:08 +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
agent 4490ea08d9 fix ITs 2026-07-09 09:58:50 +02:00
Johannes Edmeier 20827c067a
fix: Anthropic honors cache_control on AiMessage and ToolExecutionResultMessage (#5729)
## Issue
Closes #5727

## Change
`AnthropicMapper` already honored a `cache_control: "ephemeral"`
attribute on `UserMessage` (#4487). In an agentic tool loop,
`AiServices` resends the growing conversation tail (`AiMessage` +
`ToolExecutionResultMessage`) on every call, but neither of those
message types could be marked for caching, so every accumulated tool
result was rebilled at full price on each turn.

This extends the same `cache_control` handling to `AiMessage` and
`ToolExecutionResultMessage`, mirroring the existing `UserMessage`
behavior:
```java
AiMessage aiMessage = someAiMessage.toBuilder()
        .attributes(Map.of("cache_control", "ephemeral"))
        .build();
```
The cache marker is applied to the last content block of the message
(for `ToolExecutionResultMessage`, the `tool_result` block itself).
`AnthropicToolResultContent` and `AnthropicToolUseContent` gained
`cacheControl`-aware constructor/builder overloads so the marker is set
at construction time, consistent with how `AnthropicTextContent` already
does it for `UserMessage`.

## 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
- [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-08 09:28:57 +02:00
agent 400d1e2dd3 fixing tests 2026-07-06 15:42:25 +02:00
Johannes Edmeier 2f0bb9586b
Anthropic: add cache diagnostics (beta) support (#5659)
## Issue
Closes #5658

## Change
Adds opt-in support for Anthropic's `cache-diagnosis-2026-04-07` beta
feature, which reports why a prompt-cache hit was missed instead of only
showing `usage.cacheReadInputTokens` drop to zero.

- `AnthropicChatRequestParameters`: new `returnCacheDiagnostics` +
`previousMessageId` (per-request, mirrors `userId`)
- `AnthropicChatResponseMetadata#cacheDiagnostics()` exposes the result
(sync and streaming) as a new `AnthropicCacheDiagnostics` type
- Request/response shape wired through new internal API POJOs
(`AnthropicDiagnosticsParameters`, `AnthropicDiagnostics`,
`AnthropicCacheMissReason`) and the mapper
- No behavior change when the feature isn't enabled (no extra request
field, no allocation)

## 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
- [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-07-01 11:09:45 +02:00
Dmytro Liubarskyi 4480e8d5af feat(anthropic): typed Skills support for document generation (#5530 Phase 1) (#5605)
Removed auto-adding of skill "beta"
2026-07-01 11:09:00 +02:00
Benamira05 d225579243
feat(anthropic): typed Skills support for document generation (#5530 Phase 1) (#5605)
## Summary

Closes #5530 (Phase 1).

Adds a typed, ergonomic way to enable Anthropic [Agent
Skills](https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills/overview)
on `AnthropicChatModel` and `AnthropicStreamingChatModel`, so Claude can
generate real downloadable documents (`.xlsx`, `.pptx`, `.docx`, `.pdf`)
instead of only describing them:

```java
AnthropicChatModel model = AnthropicChatModel.builder()
        .apiKey(System.getenv("ANTHROPIC_API_KEY"))
        .modelName("claude-opus-4-8")
        .maxTokens(4096)
        .skills(AnthropicSkill.XLSX, AnthropicSkill.PPTX) // up to 8
        .returnServerToolResults(true)
        .build();
```

Today this requires hand-assembling a `container.skills` block via
`customParameters(...)`, manually adding the `code_execution` server
tool, and remembering three beta headers — undocumented and easy to get
wrong.

### What `skills(...)` does

When skills are configured it automatically:

- adds the `container.skills` array
(`{"type":"anthropic","skill_id":"xlsx","version":"latest"}`),
- adds the `code_execution` server tool, unless one is already
configured via `serverTools(...)` (no duplicates),
- merges the required `anthropic-beta` tokens
(`code-execution-2025-08-25`, `skills-2025-10-02`,
`files-api-2025-04-14`) with any user-supplied `beta(...)` value,
without duplicates.

The produced request matches the reference body from the issue:

```json
{
  "model": "claude-opus-4-8",
  "max_tokens": 4096,
  "container": { "skills": [{ "type": "anthropic", "skill_id": "pptx", "version": "latest" }] },
  "messages": [ ... ],
  "tools": [{ "type": "code_execution_20250825", "name": "code_execution" }]
}
```

Generated file ids remain surfacable via `returnServerToolResults(true)`
under the `AiMessage` `"server_tool_results"` attribute. Both the
blocking and streaming models are covered.

## Scope / follow-up

This is the self-contained Phase 1 from the issue. The Anthropic **Files
API client** (upload / list / delete, and the genuinely missing
**download** primitive) is intentionally left out so its surface can be
agreed first — @RyanHowell30 explicitly suggested landing Phase 1 first
and aligning on the Files-client shape before implementing Phase 2.
Happy to follow up with it once there's direction on the desired API.

Advanced cases not covered by the `.skills(...)` sugar (per-skill
version pinning, custom workspace skills, reusing a `container.id`)
remain reachable through the existing `customParameters(...)` escape
hatch; typed support for those can be layered on later if wanted.

## Test plan

- [x] New `AnthropicSkillsTest` (8 unit tests, no network): container
block contents, auto-added `code_execution` tool, no duplication when
the tool is already configured, no container/tool when no skills,
serialized request shape, and beta-header merging/de-duplication.
- [x] `mvn -pl langchain4j-anthropic test` — all unit tests pass.
- [x] `mvn -pl langchain4j-anthropic spotless:check` — clean.
- Public API change is additive (new `AnthropicSkill` enum,
`skills(...)` builder methods, and a `container` field on the internal
`AnthropicCreateMessageRequest` mirroring the existing `outputConfig`
field) — binary compatible.

---------

Co-authored-by: Benamira05 <145583236+Benamira05@users.noreply.github.com>
Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-06-29 11:01:36 +02:00
Nick Maddren 642a8ea69c
feat(anthropic): add midConversationSystemMessages option for mid-conversation system messages (#5604)
## Issue

Closes #5603

## Change

Right now the Anthropic integration folds every `SystemMessage` into the
top-level `system` field, so there's no way to use Claude Opus 4.8's
[mid-conversation system
messages](https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages).
This adds an opt-in `midConversationSystemMessages` option (default off)
that sends a `SystemMessage` appearing after the conversation has
started as a `role:"system"` entry in the `messages` array. Leading
system messages still go to the top-level `system` field, and with the
option off behaviour is unchanged.

The library doesn't enforce or reorder placement: it sends the
`SystemMessage` at whatever position the caller put it in, and Anthropic
rejects invalid placements with a 400 (an inline system message has to
follow a user turn, can't be first, and can't sit between a `tool_use`
and its `tool_result`). Those rules are noted on the option's Javadoc.

I've opened this as a draft to get a read on the approach. I don't mind
changing how it's exposed if you'd rather it worked differently.

## 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
and main modules, and they are all green
- [ ] 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-06-29 10:18:25 +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 05d06fe104 Expose unmapped raw streaming events (#5589) 2026-06-25 22:09:50 +02: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
Baqirrizvidev 3e1ddc928d
fix(anthropic): support replaying malformed JSON in tool_use arguments (#5335)
Fixes a bug where replaying historical malformed tool arguments would
throw a \JsonParseException\, breaking the error feedback loop with the
Anthropic API.

As suggested by the maintainers in #5227, this avoids parsing
\ToolExecutionRequest.arguments()\ to a \Map\ during request
construction. Instead, it uses \@JsonRawValue\ on the
\AnthropicToolUseContent.input\ field to pass the raw JSON string
directly to Jackson for serialization.

This eliminates the wasteful string -> map -> string serialization
roundtrip, prevents subtle normalizations of JSON formatting, and
preserves invalid JSON strings so that the subsequent tool execution
error result can be successfully reported back to the model.

Resolves #5227

---------

Co-authored-by: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-06-25 15:26:01 +02:00
Anurag Saxena a4d8a23204
fix(anthropic): gracefully skip [DONE] and unknown SSE frames (GH-5384) (#5398)
Closes #5384

## Summary

When an OpenAI-compatible proxy in front of Claude (e.g. LiteLLM,
OpenRouter, or a custom Anthropic->OpenAI bridge) emits a trailing
`data: [DONE]` sentinel, a comment line, or a frame with an unknown
event name, `DefaultAnthropicClient.createMessage(...)` was
deserializing the payload into `AnthropicStreamingData` and throwing
`MismatchedInputException`. The exception was swallowed by
`ServerSentEventListenerUtils.ignoringExceptions`, but it pollutes logs
and aborts trailing event processing.

This PR adds a small `isSkippableSseFrame(...)` guard in the streaming
`onEvent` callback. The guard bails out early on:

- `eventName == null` (heartbeat / keep-alive)
- `data == null` or empty (after trim)
- the OpenAI-style `"[DONE]"` sentinel
- payloads that are not JSON objects (arrays, bare scalars, raw numbers)

The raw `ServerSentEvent` is still added to `rawServerSentEvents` for
observability; the return only skips the `AnthropicStreamingData` parse
and the downstream handler dispatch.

## Why this location (not `DefaultServerSentEventParser`)

The shared `DefaultServerSentEventParser` is intentionally kept
protocol-agnostic and untouched. The same convention is already used by
`OpenAiStreamingResponseBuilder#onEvent` (OpenAI client) and
`MistralAiServerSentEventListener#onEvent` (Mistral client), which both
drop `[DONE]` at the client-listener layer. Putting the guard there
keeps the SSE parser general and matches the established pattern in the
codebase.

## Changes

-
`langchain4j-anthropic/src/main/java/dev/langchain4j/model/anthropic/internal/client/DefaultAnthropicClient.java`
  - Extract `event.event()` / `event.data()` into locals.
- Add `isSkippableSseFrame(eventName, eventData)` guard before the
`fromJson` call.
- Add the raw event to `rawServerSentEvents` even when skipping, for
parity with the existing observability behavior.

-
`langchain4j-anthropic/src/test/java/dev/langchain4j/model/anthropic/internal/client/DefaultAnthropicClientTest.java`
- New `StreamingTest#shouldIgnoreDoneSentinelAndUnknownEventFrames`:
feeds a canonical 6-event Anthropic stream followed by `[DONE]` and a
`"ping"` frame, asserts the assembled `AiMessage` is returned, the
partial-response text contains the expected tokens, and no error is
raised. The test is verified to fail (with the exact
`MismatchedInputException: ... from Array value (token
JsonToken.START_ARRAY)` from the issue) on the unfixed code and pass on
the fixed code.

## Test plan

```bash
mvn -pl langchain4j-anthropic -am test
```

All 98 unit tests in the `langchain4j-anthropic` module pass, including
the new `shouldIgnoreDoneSentinelAndUnknownEventFrames` regression test.

## Backward compatibility

No public API change. The new behavior is strictly more permissive:
previously crashing payloads (`[DONE]`, non-object JSON, `eventName ==
null`) are now silently skipped. No legitimate Anthropic streaming event
types are affected — all eight documented event types (`message_start`,
`content_block_start`, `content_block_delta`, `content_block_stop`,
`message_delta`, `message_stop`, `error`, `ping`) have a non-null,
non-empty, JSON-object `data` payload and pass the guard.

---

Reference: #5384

Co-authored-by: ENG <eng@redos.local>
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-25 14:23:49 +02:00
Eunbin Son d499aafee8
fix: Include $defs in Anthropic tool input schema for tools using schema references (#5499)
## Issue
<!-- Update with the real issue number once filed. -->
Closes #5498

## Change

`AnthropicMapper.toAnthropicTool()` did not serialize a tool parameter's
top-level `$defs` into the tool `input_schema`. Because the referenced
definitions in `JsonObjectSchema.definitions()` were dropped, a
parameter using a `$ref` (`JsonReferenceSchema`) reached Anthropic as a
dangling reference.

This is the missed sibling of PR #5131 (Closes #5133), which added
`$defs` to the structured-output path (`toAnthropicSchema`) only. The
OpenAI mapper already preserves `$defs` for the same input, so this also
restores cross-provider parity.

Changes:
- `AnthropicToolSchema`: add a `defs` field mapped to `$defs` via
`@JsonProperty("$defs")` (needed because the class uses
`SnakeCaseStrategy`), with builder support and
`equals`/`hashCode`/`toString`. The deprecated 3-arg constructor is
untouched.
- `AnthropicMapper.toAnthropicTool()`: populate `defs` from
`parameters.definitions()` when non-empty, reusing `mapDefs` and
mirroring `toAnthropicSchema`.

Backward compatible: `@JsonInclude(NON_NULL)` applies, so tools without
definitions produce identical output.

Tests (`AnthropicMapperTest`): a positive test asserts `$defs` is
present, contains the referenced key, and serializes as `"$defs"`
(regression guard for the `@JsonProperty`); a negative test asserts no
`$defs` is emitted without definitions.

## 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 <!-- core/main untouched -->
- [ ] I have added/updated the
[documentation](https://github.com/langchain4j/langchain4j/tree/main/docs/docs)
<!-- N/A, add after approval -->
- [ ] I have added an example in the [examples
repo](https://github.com/langchain4j/langchain4j-examples) (only for
"big" features) <!-- N/A -->
- [ ] I have added/updated [Spring Boot
starter(s)](https://github.com/langchain4j/langchain4j-spring) (if
applicable) <!-- N/A -->

<!-- "new maven module" and "embedding store" checklists omitted: not
applicable, this is a bug fix in an existing module. -->
2026-06-22 11:56:46 +02:00
Dmytro Liubarskyi c02e9a8a0f updated Anthropic models 2026-06-19 09:23:51 +02:00
Dmytro Liubarskyi 4fb3418f73 updated Anthropic models 2026-06-18 11:55:31 +02:00
Yash Agarwal 43249fd5bd
introduce AnthropicChatRequestParameters for per-call overrides (#5301) (#5390)
## Issue
Closes #5301

## Change
This PR introduces the provider-specific
`AnthropicChatRequestParameters` class to support per-invocation
overrides of all Anthropic-specific options, rather than baking them
into the model instance at build time.

### Key Changes:
- **Implemented `AnthropicChatRequestParameters`**: Subclasses
`DefaultChatRequestParameters` and exposes Anthropic-specific
parameters: `cacheSystemMessages`, `cacheTools`, `thinkingType`,
`thinkingBudgetTokens`, `sendThinking`, `returnThinking`,
`toolChoiceName`, `disableParallelToolUse`, and `userId`.
- **Integrated Per-Call Merging**: Updated `AnthropicChatModel` and
`AnthropicStreamingChatModel` to extract, merge, and apply parameters
dynamically on each `doChat(...)` call.
- **Narrowed Return Type**: Changed `defaultRequestParameters()` to
return the narrower `AnthropicChatRequestParameters` (with corresponding
compatibility exemptions in `revapi.json`).
- **Comprehensive Tests**: Added unit tests for merge behavior
(`overrideWith`, `defaultedBy`) and WireMock integration tests to verify
the serialized JSON payload.

### How it is Helpful (Benefits):
- **Avoids Duplicate Model Instances**: Prevents the need to instantiate
multiple model instances just to toggle features like prompt caching
(e.g. enabling caching for long agent loops, but disabling it for cheap
one-shot completions on the same model).
- **Dynamic Feature Control**: Allows applications to dynamically adjust
Extended Thinking budgets, tool choices, and parallel tool flags on a
call-by-call basis.
- **Consistent Architecture**: Aligns the Anthropic provider with other
major integrations (like OpenAI and Ollama) which already support
provider-specific request parameter overrides.

## 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: Dmytro Liubarskyi <ljubarskij@gmail.com>
2026-06-18 11:08:53 +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 9c71b83175 Docs/anthropic builder javadoc (#5331) 2026-06-01 17:09:29 +02:00
Venkateswarlu Jayakumar 8492ae52d4
Docs/anthropic builder javadoc (#5331)
<!--
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. -->


## General checklist
<!-- Please double-check the following points and mark them like this:
[X] -->
- [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
- [ ] 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-06-01 15:27:05 +02:00
Venkateswarlu Jayakumar 45e1d13175
docs: add Javadoc to AnthropicTokenCountEstimator and AnthropicModelC… (#5334)
…atalog builder methods

All public builder methods in both classes were missing documentation.
This adds @param and @return Javadoc to each method, following the style
established across the rest of the langchain4j-anthropic module.

<!--
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. -->


## General checklist
<!-- Please double-check the following points and mark them like this:
[X] -->
- [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
- [ ] 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-06-01 15:22:28 +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
Dmytro Liubarskyi 7c1a1a3921 fixing flaky ITs 2026-05-15 09:28:13 +02:00
Dmytro Liubarskyi 2e52bf2039 reduce noise in logs 2026-05-12 18:24:53 +02:00
Pedro Vieira 751bfdf3d2
feat: add per-tool strict schema enforcement on ToolSpecification (#5129)
Closes #5128

## Summary

- Adds a `Boolean strict` field to `ToolSpecification` enabling per-tool
strict schema enforcement
- When `null` (default), defers to the model-level `strictTools` setting
— fully backward compatible
- When `true`/`false`, overrides the model-level default for that
specific tool
- Updates `AnthropicMapper` and `OpenAiUtils` to resolve per-tool strict
before falling back to the model default
- Includes JSON serialization/deserialization support and tests for all
three modules

## Motivation

Anthropic limits strict tools to **20 per request**. Agentic
architectures that send 20+ tools in a single request cannot use
`strictTools(true)` on the model without hitting this limit. Per-tool
strict allows selectively enforcing strict on high-value tools while
leaving others non-strict.

## Usage

```java
ToolSpecification.builder()
    .name("runSql")
    .description("Execute a SQL query")
    .parameters(schema)
    .strict(true)   // enforce strict for this tool
    .build();
```

## Test plan

- [x] `ToolSpecificationJsonTest` — round-trip for `strict` true, false,
null; rejection of non-boolean
- [x] `AnthropicMapperTest` — per-tool true overrides model null,
per-tool false overrides model true, per-tool null falls back to model
- [x] `OpenAiUtilsTest` — same three override/fallback scenarios

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 18:54:31 +02:00
Dmytro Liubarskyi 4a3682f5ae Add name and description attributes to @P annotation (#4846) 2026-05-11 12:13:58 +02:00
Johannes Edmeier 186831df03
fix(anthropic): map JsonObjectSchema definitions to $defs (#5131)
## Issue
Closes #5133

## Change

`AnthropicMapper.toAnthropicSchema(...)` no longer mapped
`JsonObjectSchema.definitions()` to a `$defs` entry on the produced
Anthropic schema. As a result, any tool or response-format schema
containing a `JsonReferenceSchema` (e.g. recursive types, or polymorphic
AI Service return types lowered to `anyOf` of `$ref`) was serialized
with `$ref: "#/$defs/<id>"` entries and no matching `$defs` block, and
Anthropic rejected the request:

```
400 Bad Request: invalid_request_error
output_config.format.schema: Invalid schema:
Reference to non-existent definition: #/$defs/15d2a4f5-f977-330a-9c2b-b4d343c805c7
```

This is a regression introduced by #5060 (commit
[`205cb5ada`](205cb5adae),
"AI Services: support polymorphic return types and tool parameters") —
that refactor added a `JsonAnyOfSchema` branch but accidentally removed:

```java
if (!objectSchema.definitions().isEmpty()) {
    map.put("$defs", mapDefs(objectSchema.definitions()));
}
```

The pre-existing `mapDefs(...)` helper has remained in the file but
became unused.

This PR:
- Re-inserts the `definitions() -> $defs` mapping inside the
`JsonObjectSchema` branch of `toAnthropicSchema`. The existing `mapDefs`
helper is reused as-is.
- Adds `test_toAnthropicSchema_with_definitions` in
`AnthropicMapperTest`, which builds a root `JsonObjectSchema` with a
`definitions()` entry referenced via `JsonReferenceSchema` and asserts
the produced map contains a matching `$defs` block. Verified failing on
`main` and passing with the fix.

Verification:
```
mvn -pl langchain4j-anthropic -Dtest=AnthropicMapperTest test
```
All 24 tests pass.

## 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)
2026-05-08 12:24:01 +02:00
Benamira05 df352ee2e4
feat: add customHeaders support to AnthropicChatModel and AnthropicStreamingChatModel (#5101)
## Problem

`AnthropicChatModel` and `AnthropicStreamingChatModel` had no way to
attach custom HTTP headers to API requests. This is needed for use cases
like:

- Routing/tracing headers required by API gateways or proxies
- Short-lived auth tokens (OAuth, STS) that must be rotated per-request
- Tenant or correlation IDs

The feature was already available for OpenAI, Mistral, Ollama, Voyage,
and other integrations (see #4403), but was missing for Anthropic.

Closes #5100

## Solution

Added two `customHeaders` overloads to both model builders, matching the
pattern established in #4403:

```java
// Static map — headers are fixed for the lifetime of the model
AnthropicChatModel.builder()
    .customHeaders(Map.of("X-Tenant-Id", "acme"))
    ...

// Dynamic supplier — evaluated on every request, allows credential rotation
AnthropicChatModel.builder()
    .customHeaders(() -> Map.of("Authorization", tokenService.currentToken()))
    ...
```

The same API is available on `AnthropicStreamingChatModel`.

## Changes

| File | Change |
|------|--------|
| `AnthropicClient.Builder` | Added `customHeadersSupplier` field + two
`customHeaders()` builder methods |
| `DefaultAnthropicClient` | Stores the supplier; calls
`customHeadersSupplier.get()` inside `toHttpRequest()` via
`HttpRequest.Builder#addHeaders()` |
| `AnthropicChatModel.AnthropicChatModelBuilder` | Exposes
`customHeaders(Map)` and `customHeaders(Supplier<Map>)` |
| `AnthropicStreamingChatModel.AnthropicStreamingChatModelBuilder` |
Same as above |

## Tests

`AnthropicCustomHeadersTest` uses an embedded JDK `HttpServer` (no extra
dependencies) to verify headers at the HTTP level:

- Custom headers from a static `Map` reach the server
- Supplier is evaluated per-request (dynamic rotation verified across
two calls)
- Standard headers (`x-api-key`, `anthropic-version`) are not affected
- `AnthropicStreamingChatModel` sends custom headers correctly

A `null` return from the supplier is safe because
`HttpRequest.Builder#addHeaders` delegates to `isNullOrEmpty` before
iterating.

---------

Co-authored-by: Benamira05 <145583236+Benamira05@users.noreply.github.com>
2026-05-07 10:08:00 +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
Dmytro Liubarskyi 205cb5adae AI Services: support polymorphic return types and tool parameters (#5060) 2026-04-30 12:48:31 +02:00
Dmytro Liubarskyi 5a8c057a8d fixing flaky ITs 2026-04-27 13:02:16 +02:00
Dmytro Liubarskyi 8f5d18a7f6 fixing flaky tests 2026-04-24 09:43:48 +02:00
unsignedint 0482b5fe22
feat(anthropic): add thinkingDisplay option to control thinking visibility (#4950)
<!--
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!
-->

## Change
Adds a new `thinkingDisplay` builder option to `AnthropicChatModel` and
`AnthropicStreamingChatModel`, plumbed through to the `thinking.display`
field on `AnthropicThinking`. This lets callers request `"summarized"`
thinking content on Claude Opus 4.7 (where the server default is
`"omitted"`), while leaving behavior unchanged on earlier Opus/Sonnet
models that already default to `"summarized"`.

## General checklist

(I've updated the doc before PR given how small the change is)

<!-- Please double-check the following points and mark them like this:
[X] -->
- [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
- [ ] 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-23 16:41:34 +02:00
Dmytro Liubarskyi fe8b46ddfb fixing flaky tests 2026-04-22 09:40:12 +02:00
Dmytro Liubarskyi 18b3839159 Anthropic: updated AnthropicChatModelName 2026-04-21 18:29:25 +02:00
Dmytro Liubarskyi 2bbd3385dd enabled response caching for Anthropic ITs 2026-04-21 09:19:12 +02:00
Dmytro Liubarskyi 9787fb68d0 Anthropic: updated AnthropicChatModelName 2026-04-21 09:18:41 +02:00
Dmytro Liubarskyi 9901b928d2 fixing flaky ITs 2026-04-20 15:32:22 +02:00
Dmytro Liubarskyi 561cc58410 Fix https://github.com/langchain4j/langchain4j/issues/4937 2026-04-16 11:08:59 +02:00
Dmytro Liubarskyi 699e25508e fixing flaky ITs 2026-04-15 10:07:33 +02:00
Dmytro Liubarskyi e0486b6374 enabled response caching for Anthropic ITs 2026-04-13 09:27:01 +02:00
Dmytro Liubarskyi 02b5cc8d70 enabled response caching for Anthropic ITs 2026-04-10 15:41:27 +02:00
Dmytro Liubarskyi 97201e1c29 enabled response caching for Anthropic ITs 2026-04-10 10:45:50 +02:00