Skip to content

Commit cf69dae

Browse files
authored
Merge branch 'main' into main
Signed-off-by: Senrey_Song <25841017+SenreySong@users.noreply.github.com>
2 parents 1dd12ab + d662e57 commit cf69dae

File tree

56 files changed

+2009
-416
lines changed

Some content is hidden

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

56 files changed

+2009
-416
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2025-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.mcp.client.common.autoconfigure;
18+
19+
import java.util.Map;
20+
21+
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties;
22+
import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails;
23+
24+
/**
25+
* Connection details for an MCP client.
26+
*
27+
* @author Eddú Meléndez
28+
*/
29+
public interface McpSseClientConnectionDetails extends ConnectionDetails {
30+
31+
Map<String, McpSseClientProperties.SseParameters> getConnections();
32+
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2025-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.mcp.client.common.autoconfigure;
18+
19+
import java.util.Map;
20+
21+
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties;
22+
23+
public class PropertiesMcpSseClientConnectionDetails implements McpSseClientConnectionDetails {
24+
25+
private final McpSseClientProperties properties;
26+
27+
public PropertiesMcpSseClientConnectionDetails(McpSseClientProperties properties) {
28+
this.properties = properties;
29+
}
30+
31+
@Override
32+
public Map<String, McpSseClientProperties.SseParameters> getConnections() {
33+
return this.properties.getConnections();
34+
}
35+
36+
}

auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient/src/main/java/org/springframework/ai/mcp/client/httpclient/autoconfigure/SseHttpClientTransportAutoConfiguration.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer;
2929
import io.modelcontextprotocol.spec.McpSchema;
3030

31+
import org.springframework.ai.mcp.client.common.autoconfigure.McpSseClientConnectionDetails;
3132
import org.springframework.ai.mcp.client.common.autoconfigure.NamedClientMcpTransport;
33+
import org.springframework.ai.mcp.client.common.autoconfigure.PropertiesMcpSseClientConnectionDetails;
3234
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpClientCommonProperties;
3335
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties;
3436
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties.SseParameters;
@@ -73,6 +75,11 @@ public class SseHttpClientTransportAutoConfiguration {
7375

7476
private static final LogAccessor logger = new LogAccessor(SseHttpClientTransportAutoConfiguration.class);
7577

78+
@Bean
79+
PropertiesMcpSseClientConnectionDetails mcpSseClientConnectionDetails(McpSseClientProperties sseProperties) {
80+
return new PropertiesMcpSseClientConnectionDetails(sseProperties);
81+
}
82+
7683
/**
7784
* Creates a list of HTTP client-based SSE transports for MCP communication.
7885
*
@@ -84,7 +91,8 @@ public class SseHttpClientTransportAutoConfiguration {
8491
* <li>ObjectMapper for JSON processing
8592
* <li>A sync or async HTTP request customizer. Sync takes precedence.
8693
* </ul>
87-
* @param sseProperties the SSE client properties containing server configurations
94+
* @param connectionDetails the SSE client connection details containing server
95+
* configurations
8896
* @param objectMapperProvider the provider for ObjectMapper or a new instance if not
8997
* available
9098
* @param syncHttpRequestCustomizer provider for
@@ -94,7 +102,7 @@ public class SseHttpClientTransportAutoConfiguration {
94102
* @return list of named MCP transports
95103
*/
96104
@Bean
97-
public List<NamedClientMcpTransport> sseHttpClientTransports(McpSseClientProperties sseProperties,
105+
public List<NamedClientMcpTransport> sseHttpClientTransports(McpSseClientConnectionDetails connectionDetails,
98106
ObjectProvider<ObjectMapper> objectMapperProvider,
99107
ObjectProvider<McpSyncHttpClientRequestCustomizer> syncHttpRequestCustomizer,
100108
ObjectProvider<McpAsyncHttpClientRequestCustomizer> asyncHttpRequestCustomizer) {
@@ -103,7 +111,7 @@ public List<NamedClientMcpTransport> sseHttpClientTransports(McpSseClientPropert
103111

104112
List<NamedClientMcpTransport> sseTransports = new ArrayList<>();
105113

106-
for (Map.Entry<String, SseParameters> serverParameters : sseProperties.getConnections().entrySet()) {
114+
for (Map.Entry<String, SseParameters> serverParameters : connectionDetails.getConnections().entrySet()) {
107115

108116
String baseUrl = serverParameters.getValue().url();
109117
String sseEndpoint = serverParameters.getValue().sseEndpoint() != null

auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux/src/main/java/org/springframework/ai/mcp/client/webflux/autoconfigure/SseWebFluxTransportAutoConfiguration.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import com.fasterxml.jackson.databind.ObjectMapper;
2424
import io.modelcontextprotocol.client.transport.WebFluxSseClientTransport;
2525

26+
import org.springframework.ai.mcp.client.common.autoconfigure.McpSseClientConnectionDetails;
2627
import org.springframework.ai.mcp.client.common.autoconfigure.NamedClientMcpTransport;
28+
import org.springframework.ai.mcp.client.common.autoconfigure.PropertiesMcpSseClientConnectionDetails;
2729
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpClientCommonProperties;
2830
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties;
2931
import org.springframework.ai.mcp.client.common.autoconfigure.properties.McpSseClientProperties.SseParameters;
@@ -63,6 +65,11 @@
6365
matchIfMissing = true)
6466
public class SseWebFluxTransportAutoConfiguration {
6567

68+
@Bean
69+
PropertiesMcpSseClientConnectionDetails mcpSseClientConnectionDetails(McpSseClientProperties sseProperties) {
70+
return new PropertiesMcpSseClientConnectionDetails(sseProperties);
71+
}
72+
6673
/**
6774
* Creates a list of WebFlux-based SSE transports for MCP communication.
6875
*
@@ -73,14 +80,14 @@ public class SseWebFluxTransportAutoConfiguration {
7380
* <li>ObjectMapper for JSON processing
7481
* <li>Server connection parameters from properties
7582
* </ul>
76-
* @param sseProperties the SSE client properties containing server configurations
83+
* @param connectionDetails the SSE client properties containing server configurations
7784
* @param webClientBuilderProvider the provider for WebClient.Builder
7885
* @param objectMapperProvider the provider for ObjectMapper or a new instance if not
7986
* available
8087
* @return list of named MCP transports
8188
*/
8289
@Bean
83-
public List<NamedClientMcpTransport> sseWebFluxClientTransports(McpSseClientProperties sseProperties,
90+
public List<NamedClientMcpTransport> sseWebFluxClientTransports(McpSseClientConnectionDetails connectionDetails,
8491
ObjectProvider<WebClient.Builder> webClientBuilderProvider,
8592
ObjectProvider<ObjectMapper> objectMapperProvider) {
8693

@@ -89,7 +96,7 @@ public List<NamedClientMcpTransport> sseWebFluxClientTransports(McpSseClientProp
8996
var webClientBuilderTemplate = webClientBuilderProvider.getIfAvailable(WebClient::builder);
9097
var objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);
9198

92-
for (Map.Entry<String, SseParameters> serverParameters : sseProperties.getConnections().entrySet()) {
99+
for (Map.Entry<String, SseParameters> serverParameters : connectionDetails.getConnections().entrySet()) {
93100
var webClientBuilder = webClientBuilderTemplate.clone().baseUrl(serverParameters.getValue().url());
94101
String sseEndpoint = serverParameters.getValue().sseEndpoint() != null
95102
? serverParameters.getValue().sseEndpoint() : "/sse";

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-neo4j/src/test/java/org/springframework/ai/model/chat/memory/repository/neo4j/autoconfigure/Neo4jChatMemoryRepositoryAutoConfigurationIT.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ void addAndGet() {
8383
memory.deleteByConversationId(sessionId);
8484
assertThat(memory.findByConversationId(sessionId)).isEmpty();
8585

86-
AssistantMessage assistantMessage = new AssistantMessage("test answer", Map.of(),
87-
List.of(new AssistantMessage.ToolCall("id", "type", "name", "arguments")));
86+
AssistantMessage assistantMessage = AssistantMessage.builder()
87+
.content("test answer")
88+
.properties(Map.of())
89+
.toolCalls(List.of(new AssistantMessage.ToolCall("id", "type", "name", "arguments")))
90+
.build();
8891

8992
memory.saveAll(sessionId, List.of(userMessage, assistantMessage));
9093
messages = memory.findByConversationId(sessionId);

auto-configurations/models/spring-ai-autoconfigure-model-zhipuai/src/test/java/org/springframework/ai/model/zhipuai/autoconfigure/ZhiPuAiPropertiesTests.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* {@link ZhiPuAiEmbeddingProperties}.
3838
*
3939
* @author Geng Rong
40+
* @author YunKui Lu
4041
*/
4142
public class ZhiPuAiPropertiesTests {
4243

@@ -243,7 +244,9 @@ public void chatOptionsTest() {
243244
"required": ["location", "lat", "lon", "unit"]
244245
}
245246
""",
246-
"spring.ai.zhipuai.chat.options.user=userXYZ"
247+
"spring.ai.zhipuai.chat.options.user=userXYZ",
248+
"spring.ai.zhipuai.chat.options.response-format.type=json_object",
249+
"spring.ai.zhipuai.chat.options.thinking.type=disabled"
247250
)
248251
// @formatter:on
249252
.withConfiguration(AutoConfigurations.of(SpringAiRetryAutoConfiguration.class,
@@ -262,6 +265,8 @@ public void chatOptionsTest() {
262265
assertThat(chatProperties.getOptions().getTopP()).isEqualTo(0.56);
263266
assertThat(chatProperties.getOptions().getRequestId()).isEqualTo("RequestId");
264267
assertThat(chatProperties.getOptions().getDoSample()).isEqualTo(Boolean.TRUE);
268+
assertThat(chatProperties.getOptions().getResponseFormat().type()).isEqualTo("json_object");
269+
assertThat(chatProperties.getOptions().getThinking().type()).isEqualTo("disabled");
265270

266271
JSONAssert.assertEquals("{\"type\":\"function\",\"function\":{\"name\":\"toolChoiceFunctionName\"}}",
267272
chatProperties.getOptions().getToolChoice(), JSONCompareMode.LENIENT);

auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma/src/test/java/org/springframework/ai/vectorstore/chroma/autoconfigure/ChromaVectorStoreAutoConfigurationIT.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,10 @@ public void verifyThatChromaCanHandleComplexMetadataValues() {
9595

9696
var response = ChatClientResponse.builder()
9797
.chatResponse(ChatResponse.builder()
98-
.generations(List
99-
.of(new Generation(new AssistantMessage("AssistantMessage", Map.of("annotations", List.of())))))
98+
.generations(List.of(new Generation(AssistantMessage.builder()
99+
.content("AssistantMessage")
100+
.properties(Map.of("annotations", List.of()))
101+
.build())))
100102
.build())
101103
.build();
102104
var res2 = advisor.after(response, null);

mcp/common/src/main/java/org/springframework/ai/mcp/McpToolUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ public static List<ToolCallback> getToolCallbacksFromAsyncClients(List<McpAsyncC
433433
if (CollectionUtils.isEmpty(asyncMcpClients)) {
434434
return List.of();
435435
}
436-
return List.of((new AsyncMcpToolCallbackProvider(asyncMcpClients).getToolCallbacks()));
436+
return List.of((AsyncMcpToolCallbackProvider.builder().mcpClients(asyncMcpClients).build().getToolCallbacks()));
437437
}
438438

439439
@JsonIgnoreProperties(ignoreUnknown = true)

memory/repository/spring-ai-model-chat-memory-repository-cassandra/src/main/java/org/springframework/ai/chat/memory/repository/cassandra/CassandraChatMemoryRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ private Message getMessage(UdtValue udt) {
209209
Map<String, Object> props = Map.of(CONVERSATION_TS, udt.getInstant(this.conf.messageUdtTimestampColumn));
210210
switch (MessageType.valueOf(udt.getString(this.conf.messageUdtTypeColumn))) {
211211
case ASSISTANT:
212-
return new AssistantMessage(content, props);
212+
return AssistantMessage.builder().content(content).properties(props).build();
213213
case USER:
214214
return UserMessage.builder().text(content).metadata(props).build();
215215
case SYSTEM:

memory/repository/spring-ai-model-chat-memory-repository-neo4j/src/main/java/org/springframework/ai/chat/memory/repository/neo4j/Neo4jChatMemoryRepository.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,16 @@ private Message buildToolMessage(org.neo4j.driver.Record record) {
183183

184184
private Message buildAssistantMessage(org.neo4j.driver.Record record, Map<String, Object> messageMap,
185185
List<Media> mediaList) {
186-
Message message;
187-
message = new AssistantMessage(messageMap.get(MessageAttributes.TEXT_CONTENT.getValue()).toString(),
188-
record.get("metadata").asMap(Map.of()), record.get("toolCalls").asList(v -> {
189-
var toolCallMap = v.asMap();
190-
return new AssistantMessage.ToolCall((String) toolCallMap.get("id"),
191-
(String) toolCallMap.get("type"), (String) toolCallMap.get("name"),
192-
(String) toolCallMap.get("arguments"));
193-
}), mediaList);
186+
Message message = AssistantMessage.builder()
187+
.content(messageMap.get(MessageAttributes.TEXT_CONTENT.getValue()).toString())
188+
.properties(record.get("metadata").asMap(Map.of()))
189+
.toolCalls(record.get("toolCalls").asList(v -> {
190+
var toolCallMap = v.asMap();
191+
return new AssistantMessage.ToolCall((String) toolCallMap.get("id"), (String) toolCallMap.get("type"),
192+
(String) toolCallMap.get("name"), (String) toolCallMap.get("arguments"));
193+
}))
194+
.media(mediaList)
195+
.build();
194196
return message;
195197
}
196198

0 commit comments

Comments
 (0)