Skip to content

Commit 3bcb162

Browse files
authored
Merge branch 'main' into feat-graph-node-mem0
2 parents 2daa2ef + 1dadc44 commit 3bcb162

File tree

30 files changed

+850
-63
lines changed

30 files changed

+850
-63
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2024-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 com.alibaba.cloud.ai.autoconfigure.mcp.router;
18+
19+
import com.alibaba.cloud.ai.mcp.router.config.McpRouterProperties;
20+
import com.alibaba.cloud.ai.mcp.router.config.DbMcpProperties;
21+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscovery;
22+
import com.alibaba.cloud.ai.mcp.router.core.discovery.DbMcpServiceDiscovery;
23+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscoveryFactory;
24+
import jakarta.annotation.PostConstruct;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
import org.springframework.ai.mcp.server.autoconfigure.McpServerProperties;
28+
import org.springframework.boot.autoconfigure.AutoConfiguration;
29+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
30+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
31+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
32+
import org.springframework.context.annotation.Bean;
33+
34+
/**
35+
* Register DbMcpServiceDiscovery to McpServiceDiscoveryFactory.
36+
*
37+
* @author digitzh
38+
*/
39+
@AutoConfiguration
40+
@AutoConfigureAfter(McpServiceDiscoveryAutoConfiguration.class)
41+
@EnableConfigurationProperties({ McpRouterProperties.class, DbMcpProperties.class, McpServerProperties.class })
42+
@ConditionalOnProperty(prefix = McpRouterProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
43+
matchIfMissing = true)
44+
public class DbMcpRouterAutoConfiguration {
45+
46+
private static final Logger log = LoggerFactory.getLogger(DbMcpRouterAutoConfiguration.class);
47+
48+
@Bean
49+
@ConditionalOnProperty(prefix = DbMcpProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true")
50+
public DbMcpServiceDiscoveryRegistrar dbMcpServiceDiscoveryRegistrar(McpServiceDiscoveryFactory discoveryFactory,
51+
DbMcpProperties dbMcpProperties) {
52+
log.info("Creating database MCP service discovery registrar with properties: {}", dbMcpProperties);
53+
return new DbMcpServiceDiscoveryRegistrar(discoveryFactory, dbMcpProperties);
54+
}
55+
56+
public static class DbMcpServiceDiscoveryRegistrar {
57+
58+
private final McpServiceDiscoveryFactory discoveryFactory;
59+
60+
private final DbMcpProperties dbMcpProperties;
61+
62+
public DbMcpServiceDiscoveryRegistrar(McpServiceDiscoveryFactory discoveryFactory,
63+
DbMcpProperties dbMcpProperties) {
64+
this.discoveryFactory = discoveryFactory;
65+
this.dbMcpProperties = dbMcpProperties;
66+
log.info("Database MCP service discovery registrar constructor called with properties: {}",
67+
dbMcpProperties);
68+
}
69+
70+
@PostConstruct
71+
public void init() {
72+
log.info("Database MCP service discovery registrar initialized with properties: {}", dbMcpProperties);
73+
log.info("Registering DB MCP service discovery with configuration: {}", dbMcpProperties);
74+
McpServiceDiscovery dbDiscovery = new DbMcpServiceDiscovery(dbMcpProperties);
75+
discoveryFactory.registerDiscovery("database", dbDiscovery);
76+
}
77+
78+
}
79+
80+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2024-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 com.alibaba.cloud.ai.autoconfigure.mcp.router;
18+
19+
import com.alibaba.cloud.ai.mcp.router.config.McpRouterProperties;
20+
import com.alibaba.cloud.ai.mcp.router.core.discovery.FileConfigMcpServiceDiscovery;
21+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscovery;
22+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscoveryFactory;
23+
import jakarta.annotation.PostConstruct;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
26+
import org.springframework.ai.mcp.server.autoconfigure.McpServerProperties;
27+
import org.springframework.boot.autoconfigure.AutoConfiguration;
28+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
29+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
30+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
31+
import org.springframework.context.annotation.Bean;
32+
33+
/**
34+
* Register FileConfigMcpServiceDiscovery to McpServiceDiscoveryFactory.
35+
*
36+
* @author digitzh
37+
*/
38+
@AutoConfiguration
39+
@AutoConfigureAfter(McpServiceDiscoveryAutoConfiguration.class)
40+
@EnableConfigurationProperties({ McpRouterProperties.class, McpServerProperties.class })
41+
@ConditionalOnProperty(prefix = McpRouterProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
42+
matchIfMissing = true)
43+
public class FileMcpRouterAutoConfiguration {
44+
45+
private static final Logger log = LoggerFactory.getLogger(FileMcpRouterAutoConfiguration.class);
46+
47+
@Bean
48+
public FileMcpServiceDiscoveryRegistrar fileMcpServiceDiscoveryRegistrar(
49+
McpServiceDiscoveryFactory discoveryFactory, McpRouterProperties properties) {
50+
log.info("Creating file MCP service discovery registrar with properties: {}", properties);
51+
return new FileMcpServiceDiscoveryRegistrar(discoveryFactory, properties);
52+
}
53+
54+
public static class FileMcpServiceDiscoveryRegistrar {
55+
56+
private final McpServiceDiscoveryFactory discoveryFactory;
57+
58+
private final McpRouterProperties properties;
59+
60+
public FileMcpServiceDiscoveryRegistrar(McpServiceDiscoveryFactory discoveryFactory,
61+
McpRouterProperties properties) {
62+
this.discoveryFactory = discoveryFactory;
63+
this.properties = properties;
64+
log.info("File MCP service discovery registrar constructor called with properties: {}", properties);
65+
}
66+
67+
@PostConstruct
68+
public void init() {
69+
log.info("File MCP service discovery registrar initialized with properties: {}", properties);
70+
log.info("Registering file config MCP service discovery with {} services",
71+
properties.getServices() != null ? properties.getServices().size() : 0);
72+
McpServiceDiscovery fileDiscovery = new FileConfigMcpServiceDiscovery(properties);
73+
discoveryFactory.registerDiscovery("file", fileDiscovery);
74+
}
75+
76+
}
77+
78+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2024-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 com.alibaba.cloud.ai.autoconfigure.mcp.router;
18+
19+
import com.alibaba.cloud.ai.mcp.router.config.McpRouterProperties;
20+
import com.alibaba.cloud.ai.mcp.router.core.discovery.CompositeMcpServiceDiscovery;
21+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscovery;
22+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscoveryFactory;
23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
import org.springframework.boot.autoconfigure.AutoConfiguration;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
27+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
28+
import org.springframework.context.annotation.Bean;
29+
import org.springframework.context.annotation.Primary;
30+
31+
import java.util.List;
32+
33+
/**
34+
* Register McpServiceDiscovery to McpServiceDiscoveryFactory.
35+
*
36+
* @author digitzh
37+
*/
38+
@AutoConfiguration
39+
@EnableConfigurationProperties(McpRouterProperties.class)
40+
@ConditionalOnProperty(prefix = McpRouterProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
41+
matchIfMissing = true)
42+
public class McpServiceDiscoveryAutoConfiguration {
43+
44+
private static final Logger log = LoggerFactory.getLogger(McpServiceDiscoveryAutoConfiguration.class);
45+
46+
@Bean
47+
public McpServiceDiscoveryFactory mcpServiceDiscoveryFactory() {
48+
log.info("Creating MCP service discovery factory");
49+
return new McpServiceDiscoveryFactory();
50+
}
51+
52+
@Bean
53+
@Primary
54+
public McpServiceDiscovery compositeMcpServiceDiscovery(McpServiceDiscoveryFactory discoveryFactory,
55+
McpRouterProperties properties) {
56+
57+
List<String> searchOrder = getSearchOrder(properties);
58+
log.info("Creating composite MCP service discovery with search order: {}", searchOrder);
59+
60+
return new CompositeMcpServiceDiscovery(discoveryFactory, searchOrder);
61+
}
62+
63+
private List<String> getSearchOrder(McpRouterProperties properties) {
64+
if (properties.getDiscoveryOrder() != null && !properties.getDiscoveryOrder().isEmpty()) {
65+
return properties.getDiscoveryOrder();
66+
}
67+
68+
return List.of("nacos");
69+
}
70+
71+
}

auto-configurations/spring-ai-alibaba-autoconfigure-mcp-router/src/main/java/com/alibaba/cloud/ai/autoconfigure/mcp/router/NacosMcpRouterAutoConfiguration.java

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
import com.alibaba.cloud.ai.mcp.router.config.McpRouterProperties;
2525
import com.alibaba.cloud.ai.mcp.router.core.McpRouterWatcher;
2626
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscovery;
27+
import com.alibaba.cloud.ai.mcp.router.core.discovery.McpServiceDiscoveryFactory;
2728
import com.alibaba.cloud.ai.mcp.router.core.vectorstore.McpServerVectorStore;
2829
import com.alibaba.cloud.ai.mcp.router.core.vectorstore.SimpleMcpServerVectorStore;
2930
import com.alibaba.cloud.ai.mcp.router.nacos.NacosMcpServiceDiscovery;
3031
import com.alibaba.cloud.ai.mcp.router.service.McpProxyService;
3132
import com.alibaba.cloud.ai.mcp.router.service.McpRouterService;
3233
import com.alibaba.nacos.api.exception.NacosException;
34+
import jakarta.annotation.PostConstruct;
3335
import org.slf4j.Logger;
3436
import org.slf4j.LoggerFactory;
3537
import org.springframework.ai.document.MetadataMode;
@@ -38,6 +40,8 @@
3840
import org.springframework.ai.tool.ToolCallbackProvider;
3941
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
4042
import org.springframework.beans.factory.annotation.Value;
43+
import org.springframework.boot.autoconfigure.AutoConfiguration;
44+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
4145
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
4246
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4347
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -46,11 +50,15 @@
4650
import java.util.Properties;
4751

4852
/**
53+
* Register NacosMcpServiceDiscovery to McpServiceDiscoveryFactory.
54+
*
4955
* @author aias00
5056
*/
57+
@AutoConfiguration
58+
@AutoConfigureAfter(McpServiceDiscoveryAutoConfiguration.class)
5159
@EnableConfigurationProperties({ McpRouterProperties.class, NacosMcpProperties.class, McpServerProperties.class })
5260
@ConditionalOnProperty(prefix = McpRouterProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
53-
matchIfMissing = false)
61+
matchIfMissing = true)
5462
public class NacosMcpRouterAutoConfiguration {
5563

5664
private static final Logger log = LoggerFactory.getLogger(NacosMcpRouterAutoConfiguration.class);
@@ -62,7 +70,7 @@ public class NacosMcpRouterAutoConfiguration {
6270
@ConditionalOnMissingBean
6371
public EmbeddingModel embeddingModel() {
6472
if (apiKey == null || apiKey.isEmpty() || "default_api_key".equals(apiKey)) {
65-
throw new IllegalArgumentException("Environment variable DASHSCOPE_API_KEY is not set.");
73+
throw new IllegalArgumentException("Environment variable AI_DASHSCOPE_API_KEY is not set.");
6674
}
6775
DashScopeApi dashScopeApi = DashScopeApi.builder().apiKey(apiKey).build();
6876

@@ -82,13 +90,11 @@ public NacosMcpOperationService nacosMcpOperationService(NacosMcpProperties naco
8290
}
8391
}
8492

85-
/**
86-
* 配置 MCP 服务发现
87-
*/
8893
@Bean
89-
@ConditionalOnMissingBean
90-
public McpServiceDiscovery mcpServiceDiscovery(NacosMcpOperationService nacosMcpOperationService) {
91-
return new NacosMcpServiceDiscovery(nacosMcpOperationService);
94+
public NacosMcpServiceDiscoveryRegistrar nacosMcpServiceDiscoveryRegistrar(
95+
McpServiceDiscoveryFactory discoveryFactory, NacosMcpOperationService nacosMcpOperationService) {
96+
log.info("Creating Nacos MCP service discovery registrar");
97+
return new NacosMcpServiceDiscoveryRegistrar(discoveryFactory, nacosMcpOperationService);
9298
}
9399

94100
/**
@@ -138,4 +144,30 @@ public McpRouterWatcher mcpRouterWatcher(McpServiceDiscovery mcpServiceDiscovery
138144
return new McpRouterWatcher(mcpServiceDiscovery, mcpServerVectorStore, mcpRouterProperties.getServiceNames());
139145
}
140146

147+
/**
148+
* Nacos MCP服务发现注册器
149+
*/
150+
public static class NacosMcpServiceDiscoveryRegistrar {
151+
152+
private final McpServiceDiscoveryFactory discoveryFactory;
153+
154+
private final NacosMcpOperationService nacosMcpOperationService;
155+
156+
public NacosMcpServiceDiscoveryRegistrar(McpServiceDiscoveryFactory discoveryFactory,
157+
NacosMcpOperationService nacosMcpOperationService) {
158+
this.discoveryFactory = discoveryFactory;
159+
this.nacosMcpOperationService = nacosMcpOperationService;
160+
log.info("Nacos MCP service discovery registrar constructor called");
161+
}
162+
163+
@PostConstruct
164+
public void init() {
165+
log.info("Nacos MCP service discovery registrar initialized");
166+
log.info("Registering Nacos MCP service discovery");
167+
McpServiceDiscovery nacosDiscovery = new NacosMcpServiceDiscovery(nacosMcpOperationService);
168+
discoveryFactory.registerDiscovery("nacos", nacosDiscovery);
169+
}
170+
171+
}
172+
141173
}

auto-configurations/spring-ai-alibaba-autoconfigure-mcp-router/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
#
16+
17+
com.alibaba.cloud.ai.autoconfigure.mcp.router.McpServiceDiscoveryAutoConfiguration
18+
com.alibaba.cloud.ai.autoconfigure.mcp.router.FileMcpRouterAutoConfiguration
19+
com.alibaba.cloud.ai.autoconfigure.mcp.router.DbMcpRouterAutoConfiguration
1620
com.alibaba.cloud.ai.autoconfigure.mcp.router.NacosMcpRouterAutoConfiguration
1721

1822
com.alibaba.cloud.ai.autoconfigure.mcp.gateway.core.McpGatewayServerAutoConfiguration
1923
#com.alibaba.cloud.ai.autoconfigure.mcp.gateway.core.McpGatewaySseServerAutoConfiguration
2024
#com.alibaba.cloud.ai.autoconfigure.mcp.gateway.core.McpGatewayStreamableServerAutoConfiguration
2125
com.alibaba.cloud.ai.autoconfigure.mcp.gateway.nacos.NacosMcpGatewayAutoConfiguration
22-

spring-ai-alibaba-core/src/test/java/com/alibaba/cloud/ai/dashscope/chat/DashScopeMultiModalChatTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ void testStreamImageResponse() {
303303

304304
/**
305305
* Integration test for image processing with URL This test will only run if
306-
* DASHSCOPE_API_KEY environment variable is set
306+
* AI_DASHSCOPE_API_KEY environment variable is set
307307
*/
308308
@Test
309309
@Tag("integration")

spring-ai-alibaba-deepresearch/DeepResearch.http

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ Content-Type: application/json
2828
}
2929

3030

31-
### 人类反馈2:feed_back为是否接受当前计划,false时feed_back_content生效
31+
### 人类反馈2:feedback为是否接受当前计划,false时feedback_content生效
3232
POST http://localhost:8080/chat/resume
3333
Content-Type: application/json
3434

3535
{
3636
"thread_id": "__default__",
37-
"feed_back": false,
38-
"feed_back_content": "巧克力蛋糕制作技巧"
37+
"feedback": false,
38+
"feedback_content": "巧克力蛋糕制作技巧"
3939
}
4040

4141

spring-ai-alibaba-deepresearch/README-zh.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
**编程节点(给大模型提供编程能力)**
4444

4545
- Coder节点的Python执行器跑在Docker容器中,需要额外为其配置Docker信息
46-
- 在配置文件的`spring.ai.alibaba.deepreserch.python-coder.docker-host`字段中设置DockerHost,默认为`unix:///var/run/docker.sock`
47-
本项目需要使用`python:3-slim`镜像创建临时容器,也可以自己定制包含一些常用的第三方库的镜像,第三方库需要安装在镜像的`/app/dependency`文件夹里,在配置文件中设置`spring.ai.alibaba.deepreserch.python-coder.image-name`的值指定镜像名称。
46+
- 在配置文件的`spring.ai.alibaba.deepresearch.python-coder.docker-host`字段中设置DockerHost,默认为`unix:///var/run/docker.sock`
47+
本项目需要使用`python:3-slim`镜像创建临时容器,也可以自己定制包含一些常用的第三方库的镜像,第三方库需要安装在镜像的`/app/dependency`文件夹里,在配置文件中设置`spring.ai.alibaba.deepresearch.python-coder.image-name`的值指定镜像名称。
4848

4949
**RAG**
5050

spring-ai-alibaba-deepresearch/src/main/java/com/alibaba/cloud/ai/example/deepresearch/config/DeepResearchConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ public StateGraph deepResearch(ChatClient researchAgent) throws GraphStateExcept
192192
keyStrategyHashMap.put("user_upload_file", new ReplaceStrategy());
193193
keyStrategyHashMap.put("session_id", new ReplaceStrategy());
194194

195-
keyStrategyHashMap.put("feed_back", new ReplaceStrategy());
196-
keyStrategyHashMap.put("feed_back_content", new ReplaceStrategy());
195+
keyStrategyHashMap.put("feedback", new ReplaceStrategy());
196+
keyStrategyHashMap.put("feedback_content", new ReplaceStrategy());
197197

198198
// 专业知识库决策相关
199199
keyStrategyHashMap.put("use_professional_kb", new ReplaceStrategy());

0 commit comments

Comments
 (0)