mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
refactor(agent): remove legacy ConfigLoader and related factory; refactor agent launch flow
This commit is contained in:
@@ -1,16 +1,12 @@
|
|||||||
package work.slhaf.partner;
|
package work.slhaf.partner;
|
||||||
|
|
||||||
import work.slhaf.partner.common.config.PartnerAgentConfigLoader;
|
|
||||||
import work.slhaf.partner.framework.agent.Agent;
|
import work.slhaf.partner.framework.agent.Agent;
|
||||||
import work.slhaf.partner.runtime.exception.PartnerExceptionCallback;
|
import work.slhaf.partner.runtime.interaction.WebSocketGatewayRegistration;
|
||||||
import work.slhaf.partner.runtime.interaction.WebSocketGateway;
|
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Agent.newAgent(Main.class)
|
Agent.newAgent(Main.class)
|
||||||
.setAgentConfigManager(PartnerAgentConfigLoader.class)
|
.addGatewayRegistration(WebSocketGatewayRegistration.INSTANCE)
|
||||||
.setGateway(WebSocketGateway.class)
|
|
||||||
.setAgentExceptionCallback(PartnerExceptionCallback.class)
|
|
||||||
.launch();
|
.launch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package work.slhaf.partner.common.config;
|
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import work.slhaf.partner.common.exception.ConfigLoadFailedException;
|
|
||||||
import work.slhaf.partner.framework.agent.config.FileAgentConfigLoader;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.exception.ConfigNotExistException;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public final class PartnerAgentConfigLoader extends FileAgentConfigLoader {
|
|
||||||
|
|
||||||
private static final String COMMON_CONFIG_FILE = CONFIG_DIR + "common_config.json";
|
|
||||||
|
|
||||||
private Config config;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load() {
|
|
||||||
loadWebSocketConfig();
|
|
||||||
super.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadWebSocketConfig() {
|
|
||||||
File file = new File(COMMON_CONFIG_FILE);
|
|
||||||
if (!file.exists()) {
|
|
||||||
throw new ConfigNotExistException("Partner Config Not Exist: " + COMMON_CONFIG_FILE);
|
|
||||||
}
|
|
||||||
config = JSONUtil.readJSONObject(file, StandardCharsets.UTF_8).toBean(Config.class);
|
|
||||||
if (config == null || config.getAgentId() == null) {
|
|
||||||
throw new ConfigLoadFailedException("Partner Config Load Failed: " + COMMON_CONFIG_FILE);
|
|
||||||
}
|
|
||||||
int port = config.getWebSocketConfig().getPort();
|
|
||||||
if (port <= 0 || port > 65535) {
|
|
||||||
throw new ConfigLoadFailedException("Invalid Websocket port: " + port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
package work.slhaf.partner.framework.agent;
|
package work.slhaf.partner.framework.agent;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import work.slhaf.partner.framework.agent.config.AgentConfigLoader;
|
import work.slhaf.partner.framework.agent.config.ConfigCenter;
|
||||||
import work.slhaf.partner.framework.agent.exception.AgentExceptionCallback;
|
|
||||||
import work.slhaf.partner.framework.agent.exception.AgentLaunchFailedException;
|
import work.slhaf.partner.framework.agent.exception.AgentLaunchFailedException;
|
||||||
import work.slhaf.partner.framework.agent.exception.GlobalExceptionHandler;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.AgentRegisterFactory;
|
import work.slhaf.partner.framework.agent.factory.AgentRegisterFactory;
|
||||||
import work.slhaf.partner.framework.agent.interaction.AgentGateway;
|
import work.slhaf.partner.framework.agent.interaction.AgentGatewayRegistration;
|
||||||
|
import work.slhaf.partner.framework.agent.interaction.AgentGatewayRegistry;
|
||||||
|
import work.slhaf.partner.framework.agent.model.ModelRuntimeRegistry;
|
||||||
|
import work.slhaf.partner.framework.agent.state.StateCenter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <h2>Agent 启动入口</h2>
|
* <h2>Agent 启动入口</h2>
|
||||||
@@ -21,133 +20,51 @@ import java.util.concurrent.Executors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public final class Agent {
|
public final class Agent {
|
||||||
|
|
||||||
public static AgentConfigManagerStep newAgent(Class<?> clazz) {
|
public static AgentStep newAgent(Class<?> clazz) {
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
throw new AgentLaunchFailedException("Agent class 和 interaction flow context 不能为 null");
|
throw new AgentLaunchFailedException("Agent class 和 interaction flow context 不能为 null");
|
||||||
}
|
}
|
||||||
return new AgentApp(clazz);
|
return new AgentApp(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface AgentConfigManagerStep {
|
|
||||||
AgentGatewayStep setAgentConfigManager(Class<? extends AgentConfigLoader> agentConfigManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface AgentGatewayStep {
|
|
||||||
AgentStep setGateway(Class<? extends AgentGateway> gateway);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface AgentStep {
|
public interface AgentStep {
|
||||||
AgentStep addBeforeLaunchRunners(Runnable... runners);
|
AgentStep addGatewayRegistration(AgentGatewayRegistration... registrations);
|
||||||
|
|
||||||
AgentStep addAfterLaunchRunners(Runnable... runners);
|
|
||||||
|
|
||||||
AgentStep setAgentExceptionCallback(Class<? extends AgentExceptionCallback> agentExceptionCallback);
|
|
||||||
|
|
||||||
AgentStep addScanPackage(String packageName);
|
|
||||||
|
|
||||||
AgentStep addScanDir(String externalPackagePath);
|
|
||||||
|
|
||||||
void launch();
|
void launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class AgentApp implements AgentStep {
|
||||||
|
|
||||||
public static class AgentApp implements AgentStep, AgentGatewayStep, AgentConfigManagerStep {
|
|
||||||
|
|
||||||
private final ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
|
|
||||||
private final List<Runnable> beforeLaunchRunners = new ArrayList<>();
|
|
||||||
private final List<Runnable> afterLaunchRunners = new ArrayList<>();
|
|
||||||
private final Class<?> applicationClass;
|
private final Class<?> applicationClass;
|
||||||
private final CountDownLatch latch = new CountDownLatch(1);
|
private final Set<AgentGatewayRegistration> gatewayRegistrations = new LinkedHashSet<>();
|
||||||
private AgentGateway gateway;
|
|
||||||
private Class<? extends AgentConfigLoader> agentConfigManagerClass;
|
|
||||||
private Class<? extends AgentGateway> gatewayClass;
|
|
||||||
private Class<? extends AgentExceptionCallback> agentExceptionCallbackClass;
|
|
||||||
|
|
||||||
private AgentApp(Class<?> clazz) {
|
private AgentApp(Class<?> clazz) {
|
||||||
this.applicationClass = clazz;
|
this.applicationClass = clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AgentStep setGateway(Class<? extends AgentGateway> gateway) {
|
public AgentStep addGatewayRegistration(AgentGatewayRegistration... registrations) {
|
||||||
this.gatewayClass = gateway;
|
this.gatewayRegistrations.addAll(Set.of(registrations));
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AgentStep addBeforeLaunchRunners(Runnable... runners) {
|
|
||||||
this.beforeLaunchRunners.addAll(List.of(runners));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AgentStep addAfterLaunchRunners(Runnable... runners) {
|
|
||||||
this.afterLaunchRunners.addAll(List.of(runners));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AgentGatewayStep setAgentConfigManager(Class<? extends AgentConfigLoader> agentConfigManager) {
|
|
||||||
this.agentConfigManagerClass = agentConfigManager;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AgentStep setAgentExceptionCallback(Class<? extends AgentExceptionCallback> agentExceptionCallback) {
|
|
||||||
agentExceptionCallbackClass = agentExceptionCallback;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AgentStep addScanPackage(String packageName) {
|
|
||||||
AgentRegisterFactory.addScanPackage(packageName);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AgentStep addScanDir(String externalPackagePath) {
|
|
||||||
AgentRegisterFactory.addScanDir(externalPackagePath);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launch() {
|
public void launch() {
|
||||||
beforeLaunch();
|
try {
|
||||||
|
// Keep startup order explicit so registries are ready before component scanning.
|
||||||
|
StateCenter.INSTANCE.toString();
|
||||||
|
ModelRuntimeRegistry.INSTANCE.register();
|
||||||
|
AgentGatewayRegistry.INSTANCE.register();
|
||||||
|
for (AgentGatewayRegistration registration : gatewayRegistrations) {
|
||||||
|
registration.register();
|
||||||
|
}
|
||||||
|
Path externalModuleDir = ConfigCenter.INSTANCE.getPaths().getResourcesDir().resolve("module");
|
||||||
|
AgentRegisterFactory.addScanDir(externalModuleDir.toString());
|
||||||
AgentRegisterFactory.launch(applicationClass.getPackageName());
|
AgentRegisterFactory.launch(applicationClass.getPackageName());
|
||||||
afterLaunch();
|
ConfigCenter.INSTANCE.initAll();
|
||||||
}
|
ConfigCenter.INSTANCE.start();
|
||||||
|
|
||||||
private void afterLaunch() {
|
|
||||||
try {
|
|
||||||
this.gateway = gatewayClass.getDeclaredConstructor().newInstance();
|
|
||||||
executorService.execute(() -> {
|
|
||||||
gateway.launch();
|
|
||||||
latch.countDown();
|
|
||||||
log.info("Gateway 启动完毕: {}", gatewayClass.getSimpleName());
|
|
||||||
});
|
|
||||||
latch.await();
|
|
||||||
launchRunners(afterLaunchRunners);
|
|
||||||
log.info("后置任务启动完毕");
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new AgentLaunchFailedException("Agent 后置任务启动失败", e);
|
throw new AgentLaunchFailedException("Agent 启动失败", e);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void beforeLaunch() {
|
|
||||||
try {
|
|
||||||
AgentConfigLoader.setINSTANCE(agentConfigManagerClass.getDeclaredConstructor().newInstance());
|
|
||||||
log.info("配置管理器设置完毕: {}", agentConfigManagerClass.getSimpleName());
|
|
||||||
GlobalExceptionHandler.setExceptionCallback(agentExceptionCallbackClass.getDeclaredConstructor().newInstance());
|
|
||||||
log.info("异常处理回调设置完毕: {}", agentExceptionCallbackClass.getSimpleName());
|
|
||||||
launchRunners(beforeLaunchRunners);
|
|
||||||
log.info("前置任务启动完毕");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new AgentLaunchFailedException("Agent 前置任务启动失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void launchRunners(List<Runnable> runners) {
|
|
||||||
for (Runnable runner : runners) {
|
|
||||||
executorService.execute(runner);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
package work.slhaf.partner.framework.agent.config;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.pojo.ModelConfig;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Data
|
|
||||||
public abstract class AgentConfigLoader {
|
|
||||||
|
|
||||||
private static final String DEFAULT_KEY = "default";
|
|
||||||
@Setter
|
|
||||||
public static AgentConfigLoader INSTANCE;
|
|
||||||
protected HashMap<String, ModelConfig> modelConfigMap;
|
|
||||||
|
|
||||||
public void load() {
|
|
||||||
modelConfigMap = loadModelConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract HashMap<String, ModelConfig> loadModelConfig();
|
|
||||||
|
|
||||||
// Keep explicit getters for Kotlin compilation phase (without Lombok-generated methods).
|
|
||||||
public HashMap<String, ModelConfig> getModelConfigMap() {
|
|
||||||
return modelConfigMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModelConfig loadModelConfig(String modelKey) {
|
|
||||||
if (!modelConfigMap.containsKey(modelKey)) {
|
|
||||||
return modelConfigMap.get(DEFAULT_KEY);
|
|
||||||
}
|
|
||||||
return modelConfigMap.get(modelKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package work.slhaf.partner.framework.agent.config;
|
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.exception.ConfigDirNotExistException;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.exception.ConfigNotExistException;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.pojo.ModelConfig;
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.pojo.PrimaryModelConfig;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认配置工厂
|
|
||||||
* 将从当前运行目录的config文件夹下创建并读取配置
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class FileAgentConfigLoader extends AgentConfigLoader {
|
|
||||||
|
|
||||||
protected static final String CONFIG_DIR = "./config/";
|
|
||||||
protected static final String MODEL_CONFIG_DIR = "./config/model/";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HashMap<String, ModelConfig> loadModelConfig() {
|
|
||||||
File file = new File(MODEL_CONFIG_DIR);
|
|
||||||
if (!file.exists() || !file.isDirectory()) {
|
|
||||||
throw new ConfigDirNotExistException("未找到配置目录: " + MODEL_CONFIG_DIR + " 请手动创建!");
|
|
||||||
}
|
|
||||||
File[] files = file.listFiles();
|
|
||||||
if (files == null || files.length == 0) {
|
|
||||||
throw new ConfigNotExistException("在目录" + MODEL_CONFIG_DIR + "中未找到配置文件!");
|
|
||||||
}
|
|
||||||
//遍历文件获取所有配置文件并返回
|
|
||||||
HashMap<String, ModelConfig> configMap = new HashMap<>();
|
|
||||||
for (File f : files) {
|
|
||||||
if (f.isDirectory()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PrimaryModelConfig primaryModelConfig = JSONUtil.readJSONObject(f, StandardCharsets.UTF_8).toBean(PrimaryModelConfig.class);
|
|
||||||
configMap.put(primaryModelConfig.getKey(), primaryModelConfig.getModelConfig());
|
|
||||||
}
|
|
||||||
return configMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,11 +8,9 @@ import work.slhaf.partner.framework.agent.factory.component.ComponentAnnotationV
|
|||||||
import work.slhaf.partner.framework.agent.factory.component.ComponentInitHookExecutorFactory
|
import work.slhaf.partner.framework.agent.factory.component.ComponentInitHookExecutorFactory
|
||||||
import work.slhaf.partner.framework.agent.factory.component.ComponentInjectorFactory
|
import work.slhaf.partner.framework.agent.factory.component.ComponentInjectorFactory
|
||||||
import work.slhaf.partner.framework.agent.factory.component.ComponentRegisterFactory
|
import work.slhaf.partner.framework.agent.factory.component.ComponentRegisterFactory
|
||||||
import work.slhaf.partner.framework.agent.factory.config.ConfigLoaderFactory
|
|
||||||
import work.slhaf.partner.framework.agent.factory.context.AgentRegisterContext
|
import work.slhaf.partner.framework.agent.factory.context.AgentRegisterContext
|
||||||
import work.slhaf.partner.framework.agent.factory.context.ShutdownHookCollectorFactory
|
import work.slhaf.partner.framework.agent.factory.context.ShutdownHookCollectorFactory
|
||||||
import work.slhaf.partner.framework.agent.factory.exception.ExternalModuleLoadFailedException
|
import work.slhaf.partner.framework.agent.factory.exception.ExternalModuleLoadFailedException
|
||||||
import work.slhaf.partner.framework.agent.factory.exception.ExternalModulePathNotExistException
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
@@ -20,15 +18,14 @@ import java.net.URL
|
|||||||
* Agent 注册总入口,按固定顺序串联各 Factory。
|
* Agent 注册总入口,按固定顺序串联各 Factory。
|
||||||
*
|
*
|
||||||
* 启动流程:
|
* 启动流程:
|
||||||
* 1. 加载配置
|
* 1. 校验 Component 注解
|
||||||
* 2. 校验 Component 注解
|
* 2. 注册 Component/Module
|
||||||
* 3. 注册 Component/Module
|
* 3. 完成 Module 注入
|
||||||
* 4. 完成 Module 注入
|
* 4. 校验 Capability 注解
|
||||||
* 5. 校验 Capability 注解
|
* 5. 注册 Capability 代理与路由
|
||||||
* 6. 注册 Capability 代理与路由
|
* 6. 注入 Capability
|
||||||
* 7. 注入 Capability
|
* 7. 执行 Init Hook
|
||||||
* 8. 执行 Init Hook
|
* 8. 收集 Shutdown Hook
|
||||||
* 9. 收集 Shutdown Hook
|
|
||||||
*/
|
*/
|
||||||
object AgentRegisterFactory {
|
object AgentRegisterFactory {
|
||||||
private val urls: MutableList<URL> = mutableListOf()
|
private val urls: MutableList<URL> = mutableListOf()
|
||||||
@@ -37,8 +34,6 @@ object AgentRegisterFactory {
|
|||||||
fun launch(packageName: String) {
|
fun launch(packageName: String) {
|
||||||
urls.addAll(packageNameToURL(packageName))
|
urls.addAll(packageNameToURL(packageName))
|
||||||
val registerContext = AgentRegisterContext(urls)
|
val registerContext = AgentRegisterContext(urls)
|
||||||
// 0. 加载配置
|
|
||||||
ConfigLoaderFactory().execute(registerContext)
|
|
||||||
// 1. 校验 Component 级别注解是否合规,避免注入到异常位置
|
// 1. 校验 Component 级别注解是否合规,避免注入到异常位置
|
||||||
ComponentAnnotationValidatorFactory().execute(registerContext)
|
ComponentAnnotationValidatorFactory().execute(registerContext)
|
||||||
// 2. 收集所有的 AgentComponent 实例
|
// 2. 收集所有的 AgentComponent 实例
|
||||||
@@ -66,13 +61,12 @@ object AgentRegisterFactory {
|
|||||||
fun addScanDir(externalPackagePath: String) {
|
fun addScanDir(externalPackagePath: String) {
|
||||||
val file = File(externalPackagePath)
|
val file = File(externalPackagePath)
|
||||||
if (!file.exists() || !file.isDirectory) {
|
if (!file.exists() || !file.isDirectory) {
|
||||||
throw ExternalModulePathNotExistException("不存在的外部模块目录: $externalPackagePath")
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val files = file.listFiles()
|
val files = file.listFiles() ?: return
|
||||||
?: throw ExternalModulePathNotExistException("外部模块目录为空: $externalPackagePath")
|
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
throw ExternalModulePathNotExistException("外部模块目录为空: $externalPackagePath")
|
return
|
||||||
}
|
}
|
||||||
files.asSequence()
|
files.asSequence()
|
||||||
.filter { it.name.endsWith(".jar") }
|
.filter { it.name.endsWith(".jar") }
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import work.slhaf.partner.framework.agent.factory.AgentBaseFactory
|
|||||||
import work.slhaf.partner.framework.agent.factory.component.abstracts.AbstractAgentModule
|
import work.slhaf.partner.framework.agent.factory.component.abstracts.AbstractAgentModule
|
||||||
import work.slhaf.partner.framework.agent.factory.component.annotation.AgentComponent
|
import work.slhaf.partner.framework.agent.factory.component.annotation.AgentComponent
|
||||||
import work.slhaf.partner.framework.agent.factory.component.exception.ModuleFactoryInitFailedException
|
import work.slhaf.partner.framework.agent.factory.component.exception.ModuleFactoryInitFailedException
|
||||||
import work.slhaf.partner.framework.agent.factory.config.pojo.ModelConfig
|
|
||||||
import work.slhaf.partner.framework.agent.factory.context.AgentContext
|
import work.slhaf.partner.framework.agent.factory.context.AgentContext
|
||||||
import work.slhaf.partner.framework.agent.factory.context.AgentRegisterContext
|
import work.slhaf.partner.framework.agent.factory.context.AgentRegisterContext
|
||||||
import work.slhaf.partner.framework.agent.factory.context.ModuleContextData
|
import work.slhaf.partner.framework.agent.factory.context.ModuleContextData
|
||||||
@@ -30,12 +29,8 @@ class ComponentRegisterFactory : AgentBaseFactory() {
|
|||||||
|
|
||||||
override fun execute(context: AgentRegisterContext) {
|
override fun execute(context: AgentRegisterContext) {
|
||||||
val reflections = context.reflections
|
val reflections = context.reflections
|
||||||
val configFactoryContext = context.configFactoryContext
|
|
||||||
val agentContext = context.agentContext
|
val agentContext = context.agentContext
|
||||||
|
|
||||||
val modelConfigMap = configFactoryContext.modelConfigMap
|
|
||||||
val defaultConfig = modelConfigMap["default"]!!
|
|
||||||
|
|
||||||
reflections.getTypesAnnotatedWith(AgentComponent::class.java)
|
reflections.getTypesAnnotatedWith(AgentComponent::class.java)
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.filter { isConcreteClass(it) }
|
.filter { isConcreteClass(it) }
|
||||||
@@ -52,9 +47,7 @@ class ComponentRegisterFactory : AgentBaseFactory() {
|
|||||||
registerModule(
|
registerModule(
|
||||||
agentContext,
|
agentContext,
|
||||||
componentClass,
|
componentClass,
|
||||||
componentInstance,
|
componentInstance
|
||||||
modelConfigMap,
|
|
||||||
defaultConfig
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
addAdditionalComponent(agentContext, componentClass, componentInstance)
|
addAdditionalComponent(agentContext, componentClass, componentInstance)
|
||||||
@@ -66,9 +59,7 @@ class ComponentRegisterFactory : AgentBaseFactory() {
|
|||||||
private fun registerModule(
|
private fun registerModule(
|
||||||
agentContext: AgentContext,
|
agentContext: AgentContext,
|
||||||
componentClass: Class<*>,
|
componentClass: Class<*>,
|
||||||
module: AbstractAgentModule,
|
module: AbstractAgentModule
|
||||||
modelConfigMap: Map<String, ModelConfig>,
|
|
||||||
defaultConfig: ModelConfig
|
|
||||||
) {
|
) {
|
||||||
if (agentContext.modules.containsKey(module.moduleName)) {
|
if (agentContext.modules.containsKey(module.moduleName)) {
|
||||||
throw ModuleFactoryInitFailedException(
|
throw ModuleFactoryInitFailedException(
|
||||||
@@ -78,11 +69,8 @@ class ComponentRegisterFactory : AgentBaseFactory() {
|
|||||||
|
|
||||||
val launchTime = ZonedDateTime.now()
|
val launchTime = ZonedDateTime.now()
|
||||||
val modelInfo = if (module is ActivateModel) {
|
val modelInfo = if (module is ActivateModel) {
|
||||||
val modelKey = module.modelKey()
|
|
||||||
val modelConfig = modelConfigMap[modelKey] ?: defaultConfig
|
|
||||||
ModuleContextData.ModelInfo(
|
ModuleContextData.ModelInfo(
|
||||||
modelConfig.baseUrl,
|
module.modelKey(),
|
||||||
modelConfig.model,
|
|
||||||
JSONArray.parseArray(JSONObject.toJSONString(module.modulePrompt()))
|
JSONArray.parseArray(JSONObject.toJSONString(module.modulePrompt()))
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
package work.slhaf.partner.framework.agent.factory.config
|
|
||||||
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import work.slhaf.partner.framework.agent.config.AgentConfigLoader
|
|
||||||
import work.slhaf.partner.framework.agent.config.FileAgentConfigLoader
|
|
||||||
import work.slhaf.partner.framework.agent.factory.AgentBaseFactory
|
|
||||||
import work.slhaf.partner.framework.agent.factory.config.exception.ConfigNotExistException
|
|
||||||
import work.slhaf.partner.framework.agent.factory.context.AgentRegisterContext
|
|
||||||
import java.lang.reflect.Modifier
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Agent 启动阶段的配置加载工厂。
|
|
||||||
*
|
|
||||||
* 行为:
|
|
||||||
* - 使用全局 `AgentConfigLoader.INSTANCE`,为空时退回 [FileAgentConfigLoader]。
|
|
||||||
* - 加载并写入 `modelConfigMap` 到 `ConfigFactoryContext`。
|
|
||||||
* - 校验 `default` 配置是否存在。
|
|
||||||
* - 反射读取配置加载器实现类(相对基类新增)的静态字段,并写入 `AgentContext.metadata`。
|
|
||||||
*/
|
|
||||||
class ConfigLoaderFactory : AgentBaseFactory() {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val log = LoggerFactory.getLogger(ConfigLoaderFactory::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(context: AgentRegisterContext) {
|
|
||||||
val agentConfigLoader = AgentConfigLoader.INSTANCE ?: FileAgentConfigLoader().also {
|
|
||||||
AgentConfigLoader.INSTANCE = it
|
|
||||||
}
|
|
||||||
|
|
||||||
agentConfigLoader.load()
|
|
||||||
|
|
||||||
val configFactoryContext = context.configFactoryContext
|
|
||||||
configFactoryContext.modelConfigMap.putAll(agentConfigLoader.modelConfigMap)
|
|
||||||
|
|
||||||
check(configFactoryContext.modelConfigMap.keys)
|
|
||||||
collectLoaderMetadata(context, agentConfigLoader)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun check(configKeys: Set<String>) {
|
|
||||||
log.info("执行config检测...")
|
|
||||||
if (!configKeys.contains("default")) {
|
|
||||||
throw ConfigNotExistException("缺少默认配置! 需确保存在一个模型配置的key为`default`")
|
|
||||||
}
|
|
||||||
log.info("检测完毕.")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun collectLoaderMetadata(context: AgentRegisterContext, loader: AgentConfigLoader) {
|
|
||||||
val fieldNamesInBaseType = AgentConfigLoader::class.java.declaredFields
|
|
||||||
.asSequence()
|
|
||||||
.filterNot { it.isSynthetic }
|
|
||||||
.map { it.name }
|
|
||||||
.toSet()
|
|
||||||
|
|
||||||
val implementationType = loader::class.java
|
|
||||||
implementationType.declaredFields
|
|
||||||
.asSequence()
|
|
||||||
.filterNot { it.isSynthetic }
|
|
||||||
.filterNot { fieldNamesInBaseType.contains(it.name) }
|
|
||||||
.filterNot { !Modifier.isStatic(it.modifiers) }
|
|
||||||
.forEach { field ->
|
|
||||||
field.isAccessible = true
|
|
||||||
val value = field.get(loader)
|
|
||||||
context.agentContext.addMetadata(field.name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package work.slhaf.partner.framework.agent.factory.config.pojo
|
|
||||||
|
|
||||||
import lombok.Data
|
|
||||||
|
|
||||||
@Data
|
|
||||||
data class ModelConfig(
|
|
||||||
val baseUrl: String,
|
|
||||||
val apikey: String,
|
|
||||||
val model: String
|
|
||||||
)
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package work.slhaf.partner.framework.agent.factory.config.pojo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class PrimaryModelConfig {
|
|
||||||
private String key;
|
|
||||||
private ModelConfig modelConfig;
|
|
||||||
}
|
|
||||||
@@ -217,8 +217,7 @@ sealed class ModuleContextData<out T : AbstractAgentModule> {
|
|||||||
) : ModuleContextData<T>()
|
) : ModuleContextData<T>()
|
||||||
|
|
||||||
data class ModelInfo(
|
data class ModelInfo(
|
||||||
val baseUrl: String,
|
val modelKey: String,
|
||||||
val model: String,
|
|
||||||
val basePrompt: JSONArray
|
val basePrompt: JSONArray
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package work.slhaf.partner.framework.agent.factory.context
|
|||||||
import org.reflections.Reflections
|
import org.reflections.Reflections
|
||||||
import org.reflections.scanners.Scanners
|
import org.reflections.scanners.Scanners
|
||||||
import org.reflections.util.ConfigurationBuilder
|
import org.reflections.util.ConfigurationBuilder
|
||||||
import work.slhaf.partner.framework.agent.factory.config.pojo.ModelConfig
|
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
@@ -17,16 +16,11 @@ class AgentRegisterContext(urls: List<URL>) {
|
|||||||
).setUrls(urls)
|
).setUrls(urls)
|
||||||
)
|
)
|
||||||
|
|
||||||
val configFactoryContext: ConfigFactoryContext = ConfigFactoryContext()
|
|
||||||
val capabilityFactoryContext: CapabilityFactoryContext = CapabilityFactoryContext()
|
val capabilityFactoryContext: CapabilityFactoryContext = CapabilityFactoryContext()
|
||||||
val componentFactoryContext: ComponentFactoryContext = ComponentFactoryContext()
|
val componentFactoryContext: ComponentFactoryContext = ComponentFactoryContext()
|
||||||
val agentContext: AgentContext = AgentContext
|
val agentContext: AgentContext = AgentContext
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigFactoryContext {
|
|
||||||
val modelConfigMap: HashMap<String, ModelConfig> = HashMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
class CapabilityFactoryContext {
|
class CapabilityFactoryContext {
|
||||||
val cores: MutableSet<Class<*>> = LinkedHashSet()
|
val cores: MutableSet<Class<*>> = LinkedHashSet()
|
||||||
val capabilities: MutableSet<Class<*>> = LinkedHashSet()
|
val capabilities: MutableSet<Class<*>> = LinkedHashSet()
|
||||||
|
|||||||
@@ -11,10 +11,8 @@ interface AgentGatewayRegistration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun shutdown(instance: AgentGateway<*, *>) {
|
fun shutdown(instance: AgentGateway<*, *>) {
|
||||||
if (instance is AutoCloseable) {
|
|
||||||
instance.close()
|
instance.close()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun register() {
|
fun register() {
|
||||||
AgentGatewayRegistry.register(this)
|
AgentGatewayRegistry.register(this)
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ object AgentGatewayRegistry : Configurable, ConfigRegistration<AgentGatewayRegis
|
|||||||
private val registrations = linkedMapOf<String, AgentGatewayRegistration>()
|
private val registrations = linkedMapOf<String, AgentGatewayRegistration>()
|
||||||
private val runningChannels = linkedMapOf<String, RunningGateway>()
|
private val runningChannels = linkedMapOf<String, RunningGateway>()
|
||||||
|
|
||||||
init {
|
|
||||||
register()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun declare(): Map<Path, ConfigRegistration<out Config>> {
|
override fun declare(): Map<Path, ConfigRegistration<out Config>> {
|
||||||
return mapOf(Path.of("gateway", "gateway.json") to this)
|
return mapOf(Path.of("gateway", "gateway.json") to this)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user