初始化
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import tech.easyflow.ai.mapper.*;
|
||||
import tech.easyflow.common.util.SpringContextUtil;
|
||||
import tech.easyflow.common.dict.DictManager;
|
||||
import tech.easyflow.common.dict.loader.DbDataLoader;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Configuration
|
||||
public class AiDictAutoConfig {
|
||||
|
||||
@Resource
|
||||
private WorkflowMapper workflowMapper;
|
||||
@Resource
|
||||
private WorkflowCategoryMapper workflowCategoryMapper;
|
||||
@Resource
|
||||
private BotCategoryMapper botCategoryMapper;
|
||||
@Resource
|
||||
private ResourceCategoryMapper resourceCategoryMapper;
|
||||
@Resource
|
||||
private DocumentCollectionCategoryMapper documentCollectionCategoryMapper;
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void onApplicationStartup() {
|
||||
|
||||
DictManager dictManager = SpringContextUtil.getBean(DictManager.class);
|
||||
dictManager.putLoader(new DbDataLoader<>("aiWorkFlow", workflowMapper, "id", "title", null, null, false));
|
||||
dictManager.putLoader(new DbDataLoader<>("aiWorkFlowCategory", workflowCategoryMapper, "id", "category_name", null, null, false));
|
||||
dictManager.putLoader(new DbDataLoader<>("aiBotCategory", botCategoryMapper, "id", "category_name", null, null, false));
|
||||
dictManager.putLoader(new DbDataLoader<>("aiResourceCategory", resourceCategoryMapper, "id", "category_name", null, null, false));
|
||||
dictManager.putLoader(new DbDataLoader<>("aiDocumentCollectionCategory", documentCollectionCategoryMapper, "id", "category_name", null, null, false));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import com.easyagents.engine.es.ESConfig;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AiEsConfig extends ESConfig {
|
||||
|
||||
@Value("${rag.searcher.elastic.host}")
|
||||
@Override
|
||||
public void setHost(String host) {
|
||||
super.setHost(host);
|
||||
}
|
||||
|
||||
@Value("${rag.searcher.elastic.userName}")
|
||||
@Override
|
||||
public void setUserName(String userName) {
|
||||
super.setUserName(userName);
|
||||
}
|
||||
|
||||
@Value("${rag.searcher.elastic.password}")
|
||||
@Override
|
||||
public void setPassword(String password) {
|
||||
super.setPassword(password);
|
||||
}
|
||||
|
||||
@Value("${rag.searcher.elastic.indexName}")
|
||||
@Override
|
||||
public void setIndexName(String indexName) {
|
||||
super.setIndexName(indexName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import com.easyagents.search.engine.lucene.LuceneConfig;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AiLuceneConfig extends LuceneConfig {
|
||||
|
||||
@Value("${rag.searcher.lucene.indexDirPath}")
|
||||
@Override
|
||||
public void setIndexDirPath(String indexDirPath) {
|
||||
super.setIndexDirPath(indexDirPath);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
|
||||
@MapperScan("tech.easyflow.ai.mapper")
|
||||
@AutoConfiguration
|
||||
public class AiModuleConfig {
|
||||
|
||||
public AiModuleConfig() {
|
||||
System.out.println("启用模块 >>>>>>>>>> module-ai");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "node.bochaai")
|
||||
public class BochaaiProps {
|
||||
|
||||
private String apiKey;
|
||||
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public void setApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import com.easyagents.mcp.client.McpClientManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import tech.easyflow.ai.entity.Mcp;
|
||||
import tech.easyflow.ai.service.impl.McpServiceImpl;
|
||||
import tech.easyflow.common.util.StringUtil;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static tech.easyflow.ai.service.impl.McpServiceImpl.getFirstMcpServerName;
|
||||
|
||||
@Configuration
|
||||
@DependsOn("mcpServiceImpl") // 确保 mcpService 先初始化
|
||||
public class McpClientAutoConfig {
|
||||
|
||||
private final McpClientManager mcpClientManager = McpClientManager.getInstance();
|
||||
private static final Logger log = LoggerFactory.getLogger(McpClientAutoConfig.class);
|
||||
|
||||
@Resource
|
||||
private McpServiceImpl mcpService;
|
||||
|
||||
@PostConstruct
|
||||
public void initMcpClient() {
|
||||
log.info("开始初始化 MCP 客户端...");
|
||||
List<Mcp> mcpList = mcpService.list();
|
||||
log.info("获取到 MCP 配置列表,数量:{}", mcpList.size());
|
||||
mcpList.forEach(mcp -> {
|
||||
if (!mcp.getStatus()) {
|
||||
return;
|
||||
}
|
||||
String configJson = mcp.getConfigJson();
|
||||
String serverName = getFirstMcpServerName(configJson);
|
||||
if (StringUtil.hasText(serverName)) {
|
||||
try {
|
||||
mcpClientManager.registerFromJson(configJson);
|
||||
} catch (Exception e) {
|
||||
log.error("MCP服务名称:{} 注册失败", serverName, e);
|
||||
}
|
||||
log.info("MCP服务名称:{} 注册成功", serverName);
|
||||
} else {
|
||||
log.error("MCP服务名称为:{} 启动失败,配置 JSON 中未找到服务名称", mcp.getTitle());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import com.easyagents.engine.es.ElasticSearcher;
|
||||
import com.easyagents.search.engine.lucene.LuceneSearcher;
|
||||
import com.easyagents.search.engine.service.DocumentSearcher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class SearcherFactory {
|
||||
|
||||
@Autowired
|
||||
private AiLuceneConfig luceneConfig;
|
||||
|
||||
@Autowired
|
||||
private AiEsConfig aiEsConfig;
|
||||
|
||||
@Bean
|
||||
public LuceneSearcher luceneSearcher() {
|
||||
return new LuceneSearcher(luceneConfig);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ElasticSearcher elasticSearcher() {
|
||||
return new ElasticSearcher(aiEsConfig);
|
||||
}
|
||||
|
||||
|
||||
public DocumentSearcher getSearcher(String defaultSearcherType) {
|
||||
switch (defaultSearcherType) {
|
||||
case "elasticSearch":
|
||||
return new ElasticSearcher(aiEsConfig);
|
||||
case "lucene":
|
||||
default:
|
||||
return new LuceneSearcher(luceneConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package tech.easyflow.ai.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
|
||||
@Configuration
|
||||
public class ThreadPoolConfig {
|
||||
private static final Logger log = LoggerFactory.getLogger(ThreadPoolConfig.class);
|
||||
|
||||
/**
|
||||
* SSE消息发送专用线程池
|
||||
* 核心原则:IO密集型任务(网络推送),线程数 = CPU核心数 * 2 + 1
|
||||
*/
|
||||
@Bean(name = "sseThreadPool")
|
||||
public ThreadPoolTaskExecutor sseThreadPool() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
int cpuCoreNum = Runtime.getRuntime().availableProcessors(); // 获取CPU核心数(4核返回4)
|
||||
executor.setCorePoolSize(cpuCoreNum * 2); // 核心线程数
|
||||
executor.setMaxPoolSize(cpuCoreNum * 10); // 最大线程数(峰值时扩容,避免线程过多导致上下文切换)
|
||||
executor.setQueueCapacity(8000); // 任务队列容量
|
||||
executor.setKeepAliveSeconds(30); // 空闲线程存活时间:30秒(非核心线程空闲后销毁,节省资源)
|
||||
executor.setThreadNamePrefix("sse-sender-");
|
||||
|
||||
// 拒绝策略
|
||||
executor.setRejectedExecutionHandler((runnable, executorService) -> {
|
||||
log.error("SSE线程池过载!核心线程数:{},最大线程数:{},队列任务数:{}",
|
||||
executorService.getCorePoolSize(),
|
||||
executorService.getMaximumPoolSize(),
|
||||
executorService.getQueue().size());
|
||||
// 抛出自定义异常,全局捕获后返回“服务繁忙”
|
||||
throw new BusinessException("服务器忙,请稍后重试");
|
||||
});
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user