1.5.0#1765
Draft
alexheifetz wants to merge 52 commits into
Draft
Conversation
…son 3 Brings the agent platform stack onto the Spring Boot 4 line. Cascades through Spring Framework 7, Spring AI 2.0.0-M8, Jackson 3 (tools.jackson.*), Kotlin 2.2.21 (K2), and JUnit 6. Spring AI 2.0 API changes: - ChatClient.options() now takes ChatOptions.Builder<*>; bake chatOptions into the Prompt itself (preserves the ToolCallingChatOptions subtype through the advisor chain) and embed toolCallbacks via ToolCallingChatOptions.Builder so they survive the chatModel-defaults merge in addition to the spec-level .toolCallbacks() call. - Generation.getResult() / Message.getText() are now nullable; added the required !! / ?: dereferences at call sites. - Usage is non-null in 2.0; updated test mocks accordingly. - StructuredOutputConverter added getJsonSchema(); JacksonOutputConverter exposes it via a private val. - MCP customizer unified: McpSyncClientCustomizer + McpAsyncClientCustomizer → McpClientCustomizer. - MCP clientCapabilities is now non-null in test mocks. - ModelOptionsUtils.jsonToMap removed; replaced with objectMapper.readValue. Jackson 3 migration (tools.jackson.*): - POM groupIds: com.fasterxml.jackson.module/dataformat → tools.jackson.*; spring-boot pulls both jackson-bom (2.x) and tools.jackson:jackson-bom (3.x). - jackson-datatype-jsr310 removed — JavaTimeModule is built into Jackson 3. - ObjectMapper is now immutable; JsonMapper.builder() / rebuild() pattern for lenientMapper customization. - ValueDeserializer (was JsonDeserializer); ContextualDeserializer merged in. - propertyName / propertyNames (was fieldName / fieldNames). - WRITE_DATES_AS_TIMESTAMPS relocated to DateTimeFeature. - Custom MaybeReturnDeserializer rewritten against the Jackson 3 API. - Jackson 3 throws IllegalArgumentException/JacksonException (was IOException) for unserializable graphs; loosened test assertions accordingly. Spring Boot 4: - Jackson2ObjectMapperBuilder is no longer auto-configured; embabelJackson- ObjectMapper now builds via jacksonObjectMapper() directly and is autowire-eligible (dropped defaultCandidate=false) so generic ObjectMapper injections in integration tests resolve. - spring-retry was removed from the Boot 4 BOM but the API we use is unchanged; kept the library as a direct dep (spring-retry 2.0.12) rather than migrating to org.springframework.core.retry. - @AutoConfigureMockMvc moved to the new spring-boot-webmvc-test artifact under a different package; removed from CustomValidationAnnotationTest since it didn't actually use MockMvc. Spring Framework 7 / Kotlin 2.2.21 / JSpecify: - @NullMarked enforcement on Spring AI / Spring core / Jackson 3 supertypes cascades T : Any bounds into our overrides. Added -Xjspecify-annotations= ignore to embabel-build to suppress JSpecify-derived bound errors and reverted most <T : Any> bound additions, keeping them only at the unavoidable boundary (7 converter classes that directly extend Spring AI's StructuredOutputConverter / Spring's ObjectProvider). - Cast outputClass to Class<Any> at 4 converter-construction sites so unbounded <O> enclosing methods can still construct the bounded converters. - AutoRegistration ApplicationListener<ContextRefreshedEvent> bound dropped the redundant ? per Spring 7's stricter signatures. ArchUnit / victools / Jackson 3 schema generation: - victools 5.0.0 (Jackson 3 native) pulled transitively by Spring AI 2.0. - ObjectNode.deepCopy() returns ObjectNode directly (no type arg). - Schema "required" field may now nest arrays; flattened in two test sites. Tests: - FakeChatModel defaults switched from DefaultChatOptions to ToolCallingChatOptions so the prompt.options merge preserves the subtype. - 3 assertions on prompt.options.toolCallbacks count relaxed — Spring AI 2.0 routes spec toolCallbacks through ToolCallAdvisor internally rather than mirroring them onto the final prompt seen by ChatModel.call(). - assertThrows<X?> → assertThrows<X> (JUnit 6 @NullMarked). - Many test helpers bounded <T : Any> to match migrated main-source signatures. POM: - kotlin.version 2.1.10 → 2.2.21; kotlin.compiler.apiVersion 2.1 → 2.2. - spring-boot.version 4.0.6 confirmed. - spring-retry 2.0.12 as direct dep in embabel-agent-api. - spring-boot-starter-aop → aspectjweaver direct dep (Boot 4 renamed starter). - jackson-module-kotlin / jackson-dataformat-yaml groupIds migrated.
…son 3 Brings the agent platform stack onto the Spring Boot 4 line. Cascades through Spring Framework 7, Spring AI 2.0.0-M8, Jackson 3 (tools.jackson.*), Kotlin 2.2.21 (K2), and JUnit 6. Spring AI 2.0 API changes: - ChatClient.options() now takes ChatOptions.Builder<*>; bake chatOptions into the Prompt itself (preserves the ToolCallingChatOptions subtype through the advisor chain) and embed toolCallbacks via ToolCallingChatOptions.Builder so they survive the chatModel-defaults merge in addition to the spec-level .toolCallbacks() call. - Generation.getResult() / Message.getText() are now nullable; added the required !! / ?: dereferences at call sites. - Usage is non-null in 2.0; updated test mocks accordingly. - StructuredOutputConverter added getJsonSchema(); JacksonOutputConverter exposes it via a private val. - MCP customizer unified: McpSyncClientCustomizer + McpAsyncClientCustomizer → McpClientCustomizer. - MCP clientCapabilities is now non-null in test mocks. - ModelOptionsUtils.jsonToMap removed; replaced with objectMapper.readValue. Jackson 3 migration (tools.jackson.*): - POM groupIds: com.fasterxml.jackson.module/dataformat → tools.jackson.*; spring-boot pulls both jackson-bom (2.x) and tools.jackson:jackson-bom (3.x). - jackson-datatype-jsr310 removed — JavaTimeModule is built into Jackson 3. - ObjectMapper is now immutable; JsonMapper.builder() / rebuild() pattern for lenientMapper customization. - ValueDeserializer (was JsonDeserializer); ContextualDeserializer merged in. - propertyName / propertyNames (was fieldName / fieldNames). - WRITE_DATES_AS_TIMESTAMPS relocated to DateTimeFeature. - Custom MaybeReturnDeserializer rewritten against the Jackson 3 API. - Jackson 3 throws IllegalArgumentException/JacksonException (was IOException) for unserializable graphs; loosened test assertions accordingly. Spring Boot 4: - Jackson2ObjectMapperBuilder is no longer auto-configured; embabelJackson- ObjectMapper now builds via jacksonObjectMapper() directly and is autowire-eligible (dropped defaultCandidate=false) so generic ObjectMapper injections in integration tests resolve. - spring-retry was removed from the Boot 4 BOM but the API we use is unchanged; kept the library as a direct dep (spring-retry 2.0.12) rather than migrating to org.springframework.core.retry. - @AutoConfigureMockMvc moved to the new spring-boot-webmvc-test artifact under a different package; removed from CustomValidationAnnotationTest since it didn't actually use MockMvc. Spring Framework 7 / Kotlin 2.2.21 / JSpecify: - @NullMarked enforcement on Spring AI / Spring core / Jackson 3 supertypes cascades T : Any bounds into our overrides. Added -Xjspecify-annotations= ignore to embabel-build to suppress JSpecify-derived bound errors and reverted most <T : Any> bound additions, keeping them only at the unavoidable boundary (7 converter classes that directly extend Spring AI's StructuredOutputConverter / Spring's ObjectProvider). - Cast outputClass to Class<Any> at 4 converter-construction sites so unbounded <O> enclosing methods can still construct the bounded converters. - AutoRegistration ApplicationListener<ContextRefreshedEvent> bound dropped the redundant ? per Spring 7's stricter signatures. ArchUnit / victools / Jackson 3 schema generation: - victools 5.0.0 (Jackson 3 native) pulled transitively by Spring AI 2.0. - ObjectNode.deepCopy() returns ObjectNode directly (no type arg). - Schema "required" field may now nest arrays; flattened in two test sites. Tests: - FakeChatModel defaults switched from DefaultChatOptions to ToolCallingChatOptions so the prompt.options merge preserves the subtype. - 3 assertions on prompt.options.toolCallbacks count relaxed — Spring AI 2.0 routes spec toolCallbacks through ToolCallAdvisor internally rather than mirroring them onto the final prompt seen by ChatModel.call(). - assertThrows<X?> → assertThrows<X> (JUnit 6 @NullMarked). - Many test helpers bounded <T : Any> to match migrated main-source signatures. POM: - kotlin.version 2.1.10 → 2.2.21; kotlin.compiler.apiVersion 2.1 → 2.2. - spring-boot.version 4.0.6 confirmed. - spring-retry 2.0.12 as direct dep in embabel-agent-api. - spring-boot-starter-aop → aspectjweaver direct dep (Boot 4 renamed starter). - jackson-module-kotlin / jackson-dataformat-yaml groupIds migrated.
…customizer - A2A: add spring-boot-webmvc-test test dep; @AutoConfigureMockMvc moved to org.springframework.boot.webmvc.test.autoconfigure - Replace McpSyncClientCustomizer/McpAsyncClientCustomizer (Spring AI 1.x) with unified McpClientCustomizer (Spring AI 2.0) in javadoc refs
…odules - bedrock: JsonMapper for Spring AI 2.0; spring-boot-jackson test dep (JacksonAutoConfiguration relocated to o.s.b.jackson.autoconfigure) - observability: ContentCachingRequestWrapper 2-arg ctor (prod + 3 tests); ObservationRegistryCustomizer moved to micrometer-observation module - shell: javax.validation -> jakarta.validation imports - mcpserver-security: spring-boot-security + oauth2 resource-server test deps; SecurityAutoConfiguration FQN fix for Boot 4 split - mcpserver: McpSchema.Resource ctor gained title/size/meta params - webmvc: spring-boot-webmvc-test dep; MockMvc import relocation (5 tests) - deepseek/google-genai/mistral-ai: drop redundant in-builder retryTemplate call (Spring AI 2.0 expects o.s.core.retry, retries already wrap at ChatClientLlmOperations via spring-retry) - reactor: temporarily disable embabel-agent-openai and the autoconfigure/ starter modules transitively depending on it (openai*, openai-custom*, anthropic*, lmstudio*, gemini*, dockermodels*, minimax*) pending Spring AI 2.0 rewrites — OpenAiApi/AnthropicApi were removed in M8
…native SDKs Spring AI 2.0.0-M8 removed its hand-rolled OpenAiApi / AnthropicApi facades and delegates to the official openai-java (OpenAIClient) and anthropic-java (AnthropicClient) SDKs. The model builders' fluent setters were renamed (.openAiApi -> .openAiClient, .anthropicApi -> .anthropicClient, .defaultOptions -> .options) and .retryTemplate(spring-retry RetryTemplate) was dropped — retries already wrap at the ChatClientLlmOperations layer. OpenAI: - OpenAiCompatibleModelFactory: build OpenAIClient via OpenAIOkHttpClient builder (baseUrl, apiKey, customHeaders); ctor preserves restClientBuilder / webClientBuilder / completionsPath / embeddingsPath / retryTemplate params as no-ops for source compatibility with the 5 downstream subclasses (LMStudio, Gemini, Minimax, OpenAi-custom, OpenAi-autoconfigure). - OpenAiEmbeddingModel switched to the (OpenAIClient, MetadataMode, Options, ObservationRegistry) ctor. - DockerLocalModelsConfig: same migration off the now-removed OpenAiApi. - embabel-agent-openai pom: pin openai-java + openai-java-client-okhttp 4.36.0 at compile scope (overriding the BOM's 4.16.1/test) and add spring-webflux (spring-ai-openai 2.0 dropped its webflux dep but our factory's ctor still types webClientBuilder against WebClient.Builder). - LLMOpenAiGuardRailsIntegrationIT: rewire OpenAiModerationModel via OpenAiModerationModel.builder().openAiClient(...) — OpenAiModerationApi no longer exists. Anthropic: - AnthropicModelFactory: build AnthropicClient via AnthropicOkHttpClient builder (preferred over AnthropicSetup.setupSyncClient to avoid the SDK's implicit ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY env-var precedence). - AnthropicCacheTtl / AnthropicCacheOptions / AnthropicCacheStrategy promoted out of the .api subpackage in Spring AI 2.0; update imports. - Thinking config: AnthropicApi.ChatCompletionRequest.ThinkingConfig is gone — use first-class AnthropicChatOptions.Builder methods thinkingEnabled(long) / thinkingDisabled(). - UsageExtensions: AnthropicApi.Usage (int accessors) -> anthropic-java's com.anthropic.models.messages.Usage (Optional<Long> accessors). Preserve Int? return shape via .orElse(null)?.toInt(). - Test fixtures rewritten: ThinkingConfigParam exposes isEnabled() / isDisabled() as functions (not properties); UsageExtensionsTest gets a helper that wraps Usage.builder() to keep the prior positional ergonomics. Reactor: re-enable embabel-agent-openai + the seven autoconfigure/starter modules disabled in the previous commit pending these rewrites (openai, openai-custom, anthropic, lmstudio, gemini, dockermodels, minimax). Plus a small observability follow-up: gate MicrometerTracingAutoConfiguration's defaultTracingObservationHandler with @ConditionalOnBean(Tracer.class) — the bean used Tracer as a hard ctor param and crashed app startup whenever no tracing bridge (Brave / OTel) was wired in.
Spring Boot 4 / Spring AI 2.0 brought Jackson 3 (tools.jackson.*). The Spring context now publishes a tools.jackson.databind.ObjectMapper bean — autowiring the Jackson 2 com.fasterxml.jackson.databind.ObjectMapper fails with NoSuchBeanDefinition. Update the import; the readValue/writeValueAsString call sites work unchanged.
Spring Boot 4 split JacksonAutoConfiguration into its own module (spring-boot-jackson). The test's slim @SpringBootTest(classes=[…]) bootstrap doesn't import it, so neither a Jackson 2 nor Jackson 3 ObjectMapper bean is available to autowire. The mapper is only used for writeValueAsString / readValue on test DTOs — drop the @Autowired and construct it inline via jacksonObjectMapper() from tools.jackson.module.kotlin.
Same Jackson 2 → 3 migration applied earlier in examples-common: switch the com.fasterxml.jackson.module.kotlin imports to tools.jackson.module.kotlin, and collapse ObjectMapper().registerKotlinModule() to jacksonObjectMapper() (Jackson 3's ObjectMapper is immutable, so the fluent-register pattern is gone — the helper returns a mapper with the Kotlin module already wired).
Spring AI relocated AnthropicCacheTtl out of the .anthropic.api package into .anthropic. Update the test import from org.springframework.ai.anthropic.api.AnthropicCacheTtl to org.springframework.ai.anthropic.AnthropicCacheTtl. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Apache license header had its "Copyright 2024-2026 Embabel Pty Ltd." line (and trailing blank) repeated twice at the top of the file. Drop the duplicate so the header matches the standard single-block form. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spring AI 2.0 reshaped the ToolCallingChatOptions interface: the set* mutators (setToolCallbacks/setToolNames/setToolContext/ setInternalToolExecutionEnabled) were dropped in favour of builder-based configuration, and a new abstract mutate() returning ToolCallingChatOptions.Builder<*> was added. - Drop the `override` from the four tool setters; they remain as plain helpers used internally by merge() and the builder. - Implement mutate() to return a builder seeded with copy(), preserving the OCI-specific fields (compartmentId, servingMode, endpointId, apiFormat) alongside the standard chat/tool options. - Make the nested Builder implement ToolCallingChatOptions.Builder<Builder>, adding the now-required members: toolCallbacks/toolNames/toolContext (collection + vararg/pair overloads), plus clone() and combineWith() from ChatOptions.Builder. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test wrapped the parallel map in assertTimeoutPreemptively(300ms) to prove execution wasn't serial (serial = 8 × 100ms = 800ms; parallel ≈ 200ms). With only ~100ms of slack over the ideal, GC/scheduling on loaded CI runners pushed it past 300ms and it flaked (Run 1 timeout, Run 2 pass), failing the build under failOnFlakeCount=1. The maxConcurrent >= concurrencyLevel assertion already proves parallelism deterministically: each task records the peak number of simultaneously sleeping tasks, which can only reach the concurrency level under genuine parallel execution (serial would peak at 1). Drop the redundant timing- based timeout and rely on that assertion; remove the now-unused assertTimeoutPreemptively / Duration imports. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- UnfoldingTool: rename loop variable `fieldName` -> `propertyName` in tryShortcutDispatch to match the Jackson 3 fieldNames() -> propertyNames() migration. - FilteringJacksonOutputConverter: restore the `internal constructor` modifier on the primary constructor (unintentionally dropped during the migration). The `<T : Any>` bound is required by the parent and is retained; all callers use the public secondary constructors. - Revert spurious `fun <T> name` -> `fun <T>name` spacing changes across embabel-agent-api (61 sites in 9 files) to keep the git history clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…eSender Spring AI 2.0 made ToolCallingChatOptions.toolCallbacks and internalToolExecutionEnabled read-only, so the migration commented out the setters and returned a bare copy(). That silently dropped the tool callbacks whenever chatOptions was already a ToolCallingChatOptions (e.g. Anthropic / OpenAI provider options), breaking tool calling such as vector/fulltext search. Use mutate() to derive a new instance with the callbacks attached and Spring AI's automatic tool execution disabled, preserving the provider-specific subtype. This matches the pattern already used in ChatClientLlmOperations and SpringAiLlmMessageStreamer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Embabel's MicrometerTracingAutoConfiguration registers a NonEmbabelTracingObservationHandler (a DefaultTracingObservationHandler subclass) guarded by @ConditionalOnMissingBean. Spring Boot's own tracing auto-config registers a DefaultTracingObservationHandler with the same condition, so whichever runs first wins — the ordering was undefined. Make the ordering deterministic via @autoConfiguration: - afterName OpenTelemetryTracingAutoConfiguration: run after the OpenTelemetry Tracer (OtelTracer) bean exists, otherwise @ConditionalOnBean(Tracer.class) evaluates false and our handler is never registered. In Spring Boot 4 the Tracer is produced by a different class than the handler registrar, so a single beforeName is not enough. - beforeName MicrometerTracingAutoConfiguration: run before Boot registers its DefaultTracingObservationHandler, so Boot's @ConditionalOnMissingBean backs off in favour of ours. Boot's classes are referenced by name so we take no compile/runtime dependency on the spring-boot-micrometer-tracing(-opentelemetry) modules; the ordering is ignored when those modules are absent from the classpath. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pring AI 2/Jackson 3 Resolves conflicts and forward-ports HEAD's native-structured-output + JSON schema features onto the 2.0.0 baseline (Spring Boot 4, Spring AI 2.0.0-M8, Jackson 3). The merge text-merged cleanly but the incoming feature code was written against pre-2.0 APIs, so each affected file was ported, not just merged. Conflict resolutions: - ChatClientLlmOperations: keep 2.0.0's Class<Any> erasure (Spring AI 2.0 requires T : Any); re-wire the JSON converter through the adapter's jsonSchemaProvider so native structured output (#1715) survives the merge - JacksonOutputConverter / converters: jsonSchema exposed as fun getJsonSchema() (property form clashes with Spring AI 2.0 StructuredOutputConverter.getJsonSchema()) Jackson 2 -> Jackson 3 (com.fasterxml.jackson -> tools.jackson): - jsonSchemaSupport, nativeStructuredOutputSupport, OpenAiNativeStructuredOutputConfigurer and tests migrated to tools.jackson APIs - fieldNames() -> propertyNames(), elements() -> values(), ObjectMapper() -> JsonMapper.builder(), ObjectNode.set<T>() -> set(), and SerializationConfig.introspect() -> ClassIntrospector chain (introspectClassAnnotations + introspectForSerialization) Spring AI 1.x -> 2.0 (OpenAI native structured output): - ResponseFormat moved to OpenAiChatModel.ResponseFormat; jsonSchema now takes a String - options configured via mutate() builder (responseFormat/outputSchema are read-only) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sync 2.0.0-061326 with 2.0.0: port native structured output to SB4 / Spring AI 2 / Jackson 3
Adapt code from Spring AI 2.0.0-M8 to 2.0.0 GA after the merge in 90d0e1e. - JacksonOutputConverter: LoggingMarkers removed in GA -> SLF4J MarkerFactory.getMarker("SENSITIVE") - SpringAiLlmMessageSender: drop removed per-request internalToolExecutionEnabled flag (internal tool execution is now controlled at the ChatModel level) - ChatClientLlmTransformerTest: DefaultChatOptions() ctor now protected -> ChatOptions.builder().build() - Bedrock: drop removed ToolExecutionEligibilityPredicate (use 5-arg BedrockProxyChatModel ctor); convert Cohere Properties.Options -> BedrockCohereEmbeddingOptions Build state: core modules + Bedrock compile. Remaining provider modules (Anthropic, Gemini, OCI, etc.) still need the same GA migration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
OllamaChatModel/OllamaEmbeddingModel builders renamed defaultOptions() -> options() in Spring AI 2.0. Update both call sites in OllamaModelsConfig. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ChatModel builders renamed defaultOptions() -> options() in Spring AI 2.0. Update DeepSeekModelsConfig and MistralAiModelsConfig. (Bedrocks .defaultOptions is on embabels own EmbabelBedrockProxyChatModelBuilder and is intentionally unchanged.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spring AI 2.0.0 moved GoogleGenAiEmbeddingConnectionDetails to the org.springframework.ai.google.genai.embedding sub-package. Update the import in GoogleGenAiModelsConfig. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
OciGenAiChatOptions hand-implements Spring AI options interfaces, which changed in 2.0.0: - ToolCallingChatOptions dropped toolNames + internalToolExecutionEnabled; ChatOptions dropped copy(). Drop override on these (getters, builder methods, copy) and keep them as OCI-internal members. - merge(): stop reading toolNames/internalToolExecutionEnabled off the Spring AI ToolCallingChatOptions interface; merge them only between OciGenAiChatOptions instances. - Test: call getInternalToolExecutionEnabled() explicitly (property name now resolves to the private backing var). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spring AI 2.0 GA ChatClient no longer preserves the ToolCallingChatOptions subtype through its option merge; a real ChatModel now receives a plain ChatOptions (tools flow via the ToolCallingAdvisor / spec-level toolCallbacks). The test fakes asserted prompt.options is ToolCallingChatOptions, which held in M8 but not GA. - FakeChatModel and the streaming guardrail fake now accept any ChatOptions instead of throwing. - optionsPassed typed as List<ChatOptions>; the "presents no tools" assertion reads toolCallbacks null-safe via an as? cast (also handles getToolCallbacks() now returning null when empty). - Removed a dead options assertion in the delaying fake. Test-only; no production change. Resolves the 11 failures in ChatClientLlmOperationsTest / ChatClientLlmOperationsThinkingTest / StreamingChatClientOperationsGuardRailTest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ng AI 2.0) Spring AI 2.0 spring-ai-anthropic depends only on anthropic-java-core, not the OkHttp client. AnthropicModelFactory uses AnthropicOkHttpClient directly, so the module must declare anthropic-java-client-okhttp explicitly. Version is supplied by the embabel-build BOM (anthropic-java.version) - no inline version here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nsDetails anthropic-java 2.40.1 (pinned transitively by spring-ai-anthropic 2.0.0) made Usage.Builder.outputTokensDetails a required field. The anthropicUsage test helper did not set it, so Usage.build() threw IllegalStateException on all 12 tests. Set it to Optional.empty(), consistent with the helpers other required-but-empty fields. Test-only. (Surfaced only on CI: local .m2 still had anthropic-java 2.34.0 and the module was built with -DskipTests.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spring AI 2.0.0 GA Migration
Synchronize with 1.0 06222026
Spring AI 2.0 dropped the hand-rolled AnthropicApi in favour of the official anthropic-java SDK and relocated the cache option types. - AnthropicOptionsConverter: move AnthropicCacheOptions/AnthropicCacheStrategy out of the removed `.anthropic.api` package and replace the AnthropicApi.ChatCompletionRequest.ThinkingConfig(...) chain with the first-class thinkingEnabled(tokenBudget) / thinkingDisabled() builder methods. - pom: declare anthropic-java-client-okhttp explicitly (spring-ai-anthropic only pulls anthropic-java-core); version managed by the embabel-build BOM. - AnthropicModelsConfig: drop the duplicate inline AnthropicOptionsConverter left over from the monolithic layout; the config now delegates to the core module's converter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ContentPart deserializer was still on Jackson 2 (com.fasterxml.jackson), so the Jackson 3 ObjectMapper never saw the @JsonDeserialize annotation and failed to construct the abstract ContentPart type. - ContentPart: @JsonDeserialize import -> tools.jackson.databind.annotation - ContentPartDeserializer: JsonDeserializer -> ValueDeserializer, parser.codec.readTree(...) -> context.readTree(parser), and JsonMappingException.from(...) -> MismatchedInputException.from(...). Fixes the MessageSerializationTest deserialization failures. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test imported org.junit.jupiter.api.Assertions.* (static members only) but every call site uses the qualified form Assertions.assertEquals(...), so the Assertions class reference was unresolved. Import the class itself. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



This pull request updates the
embabel-agent-a2aandembabel-agent-anthropicmodules for compatibility with Spring Boot 4 and Spring AI 2.0, and migrates from the legacy Jackson and Anthropic APIs to their new locations and idioms. The changes include dependency and import updates, code migration to new SDKs, and minor code cleanups. The most important changes are grouped below.Spring Boot 4 and Spring AI 2.0 Compatibility:
embabel-agent-a2a/pom.xmlandembabel-agent-anthropic/pom.xmlto1.5.0-SNAPSHOTto align with the new platform versions. [1] [2]spring-boot-webmvc-test) and updated test annotations and imports to match the new package structure (e.g.,AutoConfigureMockMvcmoved toorg.springframework.boot.webmvc.test.autoconfigure). [1] [2]Migration to New Jackson Package:
com.fasterxml.jacksonimports withtools.jacksonequivalents throughout the codebase for both main and test sources. [1] [2] [3] [4] [5]Anthropic SDK and Spring AI 2.0 Migration:
AnthropicModelFactory.ktto use the officialanthropic-javaSDK (AnthropicClientandAnthropicOkHttpClient), removing all usage of the deprecatedAnthropicApi,RestClient, andWebClient. The HTTP client setup is now handled directly via the SDK, and the builder parameters are updated for compatibility. [1] [2] [3] [4]AnthropicApi.ChatCompletionRequest.ThinkingConfigis no longer available in Spring AI 2.0. [1] [2]anthropic-java-client-okhttpdependency explicitly inembabel-agent-anthropic/pom.xmlto support the new SDK.Minor Cleanups:
These updates ensure the codebase is compatible with the latest versions of Spring Boot and Spring AI, and that it leverages the official Anthropic SDK for all LLM interactions.