Skip to content

Commit 0aaecac

Browse files
committed
Upgrade to Spring AI 2.0.0-RC1 and fix null guards in logging advisors
- Bump spring-ai to 2.0.0-RC1, spring-framework to 7.0.7, library to 0.9.0 - Remove ToolCallAdvisor (now auto-configured by the framework) - Replace defaultToolCallbacks() with defaultTools() - Replace ModelOptionsUtils.toJsonString() with JsonHelper.toJson() - Rename spring.ai.openai-sdk.* properties to spring.ai.openai.* - Replace toolOptions.copy() with mutate().build() in AutoMemoryToolsAdvisor - Add null guard for getToolCallbacks() in all MyLoggingAdvisor copies - Add null guard for chatResponse() in subagent MyLoggingAdvisor.after() - Add migration guide docs/tools/migration-0.9.md Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
1 parent 5548e80 commit 0aaecac

43 files changed

Lines changed: 309 additions & 184 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Use the BOM to manage versions consistently across all modules:
9494
<dependency>
9595
<groupId>org.springaicommunity</groupId>
9696
<artifactId>spring-ai-agent-utils-bom</artifactId>
97-
<version>0.7.0</version>
97+
<version>0.9.0</version>
9898
<type>pom</type>
9999
<scope>import</scope>
100100
</dependency>
@@ -115,7 +115,7 @@ Or add the core library directly:
115115
<dependency>
116116
<groupId>org.springaicommunity</groupId>
117117
<artifactId>spring-ai-agent-utils</artifactId>
118-
<version>0.7.0</version>
118+
<version>0.9.0</version>
119119
</dependency>
120120
```
121121

@@ -208,7 +208,7 @@ This project reimplements key Claude Code features based on:
208208

209209
- Java 17+
210210
- Spring Boot 3.x / 4.x
211-
- Spring AI 2.0.0-M4 or later
211+
- Spring AI 2.0.0-RC1 or later
212212
- Maven 3.6+
213213

214214
## Building

docs/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Use the BOM to manage versions consistently across all modules:
4242
<dependency>
4343
<groupId>org.springaicommunity</groupId>
4444
<artifactId>spring-ai-agent-utils-bom</artifactId>
45-
<version>0.7.0</version>
45+
<version>0.9.0</version>
4646
<type>pom</type>
4747
<scope>import</scope>
4848
</dependency>
@@ -63,14 +63,14 @@ Or add the core library directly:
6363
<dependency>
6464
<groupId>org.springaicommunity</groupId>
6565
<artifactId>spring-ai-agent-utils</artifactId>
66-
<version>0.7.0</version>
66+
<version>0.9.0</version>
6767
</dependency>
6868
```
6969

7070
_Check the latest version:_ [![](https://img.shields.io/maven-central/v/org.springaicommunity/spring-ai-agent-utils.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/org.springaicommunity/spring-ai-agent-utils)
7171

7272
!!! note
73-
You need Spring AI version `2.0.0-M4` or later.
73+
You need Spring AI version `2.0.0-RC1` or later.
7474

7575
**2. Configure your agent:**
7676

@@ -147,7 +147,7 @@ public class Application {
147147

148148
- Java 17+
149149
- Spring Boot 3.x / 4.x
150-
- Spring AI 2.0.0-M4 or later
150+
- Spring AI 2.0.0-RC1 or later
151151
- Maven 3.6+
152152

153153
## Building

docs/tools/migration-0.9.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Migration Guide: 0.7.x to 0.9.0
2+
3+
This release upgrades the Spring AI dependency from `2.0.0-M7` to `2.0.0-RC1` and Spring Framework from `7.0.1` to `7.0.7`. Several Spring AI APIs changed in ways that require updates to application code.
4+
5+
## Dependency Version
6+
7+
```xml
8+
<dependency>
9+
<groupId>org.springaicommunity</groupId>
10+
<artifactId>spring-ai-agent-utils</artifactId>
11+
<version>0.9.0</version>
12+
</dependency>
13+
```
14+
15+
## Spring AI API Changes
16+
17+
### `ToolCallAdvisor` removed
18+
19+
`ToolCallAdvisor` is deprecated and no longer needs to be registered. Tool calling is now handled automatically by the framework when tools are present on the `ChatClient`.
20+
21+
**Before:**
22+
23+
```java
24+
chatClientBuilder.defaultAdvisors(
25+
ToolCallAdvisor.builder().build(),
26+
MessageChatMemoryAdvisor.builder(...).build());
27+
```
28+
29+
**After:**
30+
31+
```java
32+
chatClientBuilder.defaultAdvisors(
33+
MessageChatMemoryAdvisor.builder(...).build());
34+
```
35+
36+
If you were using `disableInternalConversationHistory()` or `conversationHistoryEnabled(false)`, that behaviour is now controlled by advisor ordering — see the [Memory advisor ordering](#memory-advisor-ordering) section below.
37+
38+
### `defaultToolCallbacks()``defaultTools()`
39+
40+
`ChatClient.Builder.defaultToolCallbacks()` is deprecated. Use `defaultTools()` instead. It accepts the same types: individual `ToolCallback` objects, `ToolCallbackProvider` instances, and annotated POJO classes.
41+
42+
**Before:**
43+
44+
```java
45+
chatClientBuilder
46+
.defaultToolCallbacks(SkillsTool.builder().build())
47+
.defaultToolCallbacks(mcpToolCallbackProvider);
48+
```
49+
50+
**After:**
51+
52+
```java
53+
chatClientBuilder
54+
.defaultTools(SkillsTool.builder().build())
55+
.defaultTools(mcpToolCallbackProvider);
56+
```
57+
58+
### OpenAI starter artifact renamed
59+
60+
The OpenAI SDK starter artifact has been renamed:
61+
62+
| Before | After |
63+
|--------|-------|
64+
| `spring-ai-starter-model-openai-sdk` | `spring-ai-starter-model-openai` |
65+
66+
```xml
67+
<!-- After -->
68+
<dependency>
69+
<groupId>org.springframework.ai</groupId>
70+
<artifactId>spring-ai-starter-model-openai</artifactId>
71+
</dependency>
72+
```
73+
74+
### OpenAI property prefix renamed
75+
76+
All `spring.ai.openai-sdk.*` properties are renamed to `spring.ai.openai.*`:
77+
78+
| Before | After |
79+
|--------|-------|
80+
| `spring.ai.openai-sdk.api-key` | `spring.ai.openai.api-key` |
81+
| `spring.ai.openai-sdk.chat.options.model` | `spring.ai.openai.chat.options.model` |
82+
| `spring.ai.openai-sdk.chat.options.temperature` | `spring.ai.openai.chat.options.temperature` |
83+
84+
### `ModelOptionsUtils.toJsonString()` removed
85+
86+
If you reference `ModelOptionsUtils.toJsonString()` in custom advisor or tool code, replace it with `JsonHelper`:
87+
88+
**Before:**
89+
90+
```java
91+
import org.springframework.ai.model.ModelOptionsUtils;
92+
93+
String json = ModelOptionsUtils.toJsonString(object);
94+
```
95+
96+
**After:**
97+
98+
```java
99+
import org.springframework.ai.util.JsonHelper;
100+
101+
String json = new JsonHelper().toJson(object);
102+
```
103+
104+
### `ToolCallingChatOptions.copy()` removed
105+
106+
`copy()` has been removed from the `ToolCallingChatOptions` interface. Use `mutate().build()` instead:
107+
108+
**Before:**
109+
110+
```java
111+
ToolCallingChatOptions copy = toolOptions.copy();
112+
```
113+
114+
**After:**
115+
116+
```java
117+
ToolCallingChatOptions copy = toolOptions.mutate().build();
118+
```
119+
120+
### `DefaultToolCallingChatOptions` public constructor removed
121+
122+
The no-arg public constructor is no longer available. Use the builder:
123+
124+
**Before:**
125+
126+
```java
127+
new DefaultToolCallingChatOptions()
128+
```
129+
130+
**After:**
131+
132+
```java
133+
DefaultToolCallingChatOptions.builder().build()
134+
```
135+
136+
## Memory Advisor Ordering
137+
138+
`MessageChatMemoryAdvisor` must be placed **outside** (before) the tool-calling loop so that memory is only read/written once per user turn rather than on every tool-call iteration. The advisor's default order (`Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER = HIGHEST_PRECEDENCE + 200`) already satisfies this — do not override it with a higher value.
139+
140+
**Incorrect** (places memory inside the tool-call loop):
141+
142+
```java
143+
MessageChatMemoryAdvisor.builder(memory)
144+
.order(Ordered.HIGHEST_PRECEDENCE + 1000) // wrong — higher value = inner = inside tool loop
145+
.build()
146+
```
147+
148+
**Correct** (use the default order):
149+
150+
```java
151+
MessageChatMemoryAdvisor.builder(memory).build()
152+
```
153+
154+
The auto-configured `ToolCallingAdvisor` sits at `HIGHEST_PRECEDENCE + 300`. Memory at the default `HIGHEST_PRECEDENCE + 200` is numerically lower and therefore outermost, wrapping all tool calls in a single memory read/write cycle.

examples/ask-user-question-demo/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
<properties>
2121
<java.version>17</java.version>
2222
<maven.deploy.skip>true</maven.deploy.skip>
23-
<spring-ai.version>2.0.0-SNAPSHOT</spring-ai.version>
23+
<spring-ai.version>2.0.0-RC1</spring-ai.version>
2424
</properties>
2525

2626
<dependencies>
2727

2828
<dependency>
2929
<groupId>org.springaicommunity</groupId>
3030
<artifactId>spring-ai-agent-utils</artifactId>
31-
<version>0.6.0</version>
31+
<version>0.9.0-SNAPSHOT</version>
3232
</dependency>
3333

3434
<dependency>
@@ -49,7 +49,7 @@
4949

5050
<!-- <dependency>
5151
<groupId>org.springframework.ai</groupId>
52-
<artifactId>spring-ai-starter-model-openai-sdk</artifactId>
52+
<artifactId>spring-ai-starter-model-openai</artifactId>
5353
</dependency> -->
5454

5555
<dependency>

examples/ask-user-question-demo/src/main/java/org/springaicommunity/agent/Application.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77

88
import org.springframework.ai.chat.client.ChatClient;
99
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
10-
import org.springframework.ai.chat.client.advisor.ToolCallAdvisor;
1110
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
1211
import org.springframework.boot.CommandLineRunner;
1312
import org.springframework.boot.SpringApplication;
1413
import org.springframework.boot.autoconfigure.SpringBootApplication;
1514
import org.springframework.context.annotation.Bean;
15+
import org.springframework.core.Ordered;
1616

1717
@SpringBootApplication
1818
public class Application {
19-
19+
2020
public static void main(String[] args) {
2121
SpringApplication.run(Application.class, args);
2222
}
@@ -35,8 +35,8 @@ CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder) {
3535
.build())
3636

3737
.defaultAdvisors(
38-
ToolCallAdvisor.builder().disableInternalConversationHistory().build(),
39-
MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().maxMessages(500).build()).build())
38+
MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().maxMessages(500).build())
39+
.order(Ordered.HIGHEST_PRECEDENCE + 1000).build())
4040

4141
.build();
4242
// @formatter:on
@@ -52,4 +52,5 @@ CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder) {
5252
}
5353
};
5454
}
55+
5556
}

examples/ask-user-question-demo/src/main/resources/application.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ spring.ai.anthropic.chat.options.max-tokens=1000
88

99

1010
## OpenAI SDK
11-
spring.ai.openai-sdk.api-key=${OPENAI_API_KEY}
12-
spring.ai.openai-sdk.chat.options.model=gpt-5-mini-2025-08-07
13-
spring.ai.openai-sdk.chat.options.temperature=1.0
11+
spring.ai.openai.api-key=${OPENAI_API_KEY}
12+
spring.ai.openai.chat.options.model=gpt-5-mini-2025-08-07
13+
spring.ai.openai.chat.options.temperature=1.0
1414

1515

1616
## Google GenAI SDK

examples/code-agent-demo/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
<properties>
2121
<java.version>17</java.version>
2222
<maven.deploy.skip>true</maven.deploy.skip>
23-
<spring-ai.version>2.0.0-SNAPSHOT</spring-ai.version>
23+
<spring-ai.version>2.0.0-RC1</spring-ai.version>
2424
</properties>
2525

2626
<dependencies>
2727

2828
<dependency>
2929
<groupId>org.springaicommunity</groupId>
3030
<artifactId>spring-ai-agent-utils</artifactId>
31-
<version>0.6.0</version>
31+
<version>0.9.0-SNAPSHOT</version>
3232
</dependency>
3333

3434
<!-- <dependency>
@@ -38,7 +38,7 @@
3838

3939
<!-- <dependency>
4040
<groupId>org.springframework.ai</groupId>
41-
<artifactId>spring-ai-starter-model-openai-sdk</artifactId>
41+
<artifactId>spring-ai-starter-model-openai</artifactId>
4242
</dependency> -->
4343

4444
<dependency>

examples/code-agent-demo/src/main/java/org/springaicommunity/agent/Application.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import org.springframework.ai.chat.client.ChatClient;
1818
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
19-
import org.springframework.ai.chat.client.advisor.ToolCallAdvisor;
2019
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
2120
import org.springframework.ai.tool.ToolCallbackProvider;
2221
import org.springframework.beans.factory.annotation.Value;
@@ -52,10 +51,10 @@ CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder,
5251
.param(AgentEnvironment.AGENT_MODEL_KNOWLEDGE_CUTOFF_KEY, agentModelKnowledgeCutoff))
5352

5453
// AirBnb MCP Tools
55-
.defaultToolCallbacks(mcpToolCallbackProvider)
54+
.defaultTools(mcpToolCallbackProvider)
5655

5756
// Skills tool
58-
.defaultToolCallbacks(SkillsTool.builder().addSkillsResources(skillPaths).build())
57+
.defaultTools(SkillsTool.builder().addSkillsResources(skillPaths).build())
5958

6059
// Todo management tool
6160
.defaultTools(TodoWriteTool.builder().build())
@@ -76,17 +75,14 @@ CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder,
7675

7776
// Advisors
7877
.defaultAdvisors(
79-
ToolCallAdvisor.builder()
80-
.conversationHistoryEnabled(false)
81-
.build(), // tool calling advisor
8278
MessageChatMemoryAdvisor.builder(MessageWindowChatMemory.builder().maxMessages(500).build())
8379
.order(Ordered.HIGHEST_PRECEDENCE + 1000)
8480
.build())
8581
// logging advisor
8682
// MyLoggingAdvisor.builder()
8783
// .showAvailableTools(false)
8884
// .showSystemMessage(false)
89-
// .build())
85+
// .build())
9086
.build();
9187
// @formatter:on
9288

@@ -101,4 +97,5 @@ CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder,
10197
}
10298
};
10399
}
100+
104101
}

0 commit comments

Comments
 (0)