mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
完善配置工厂遗留问题; 初步完善 AgentRunningFlow 流程相关。
- 修复了 ActivateModel 中 model 实例化后却未赋值的问题 - 调整 Api 包下目录结构, 新增 runtime 包用于存放运行时相关类 - 完善 AgentConfigManager 基类以及对应的默认实现类中的加载、序列化以及更新逻辑 - 将异常类型分类为‘启动时异常’与‘运行时异常’,前者将直接导致启动停止,后者可通过异常回调实现进行处理 - 新增全局异常处理类以及默认的异常回调实现 - 新增几个异常类 - 完善 Agent 链式构建流程, 实际上只是做了一些方法转发,但毕竟那些可提供自定义实现的,不管是factory还是manager、handler, 它们都过于分散了。
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,3 +49,4 @@ build/
|
||||
/Partner-Core/src/main/java/src/test/java/memory/result/primary_input.json
|
||||
/Partner-Core/src/main/java/src/main/resources/prompt/module/memory/topic_extractor.json.bak
|
||||
/backup/
|
||||
/Partner-Main/src/test/java/text/test.json
|
||||
|
||||
@@ -26,6 +26,7 @@ maxNumHashImportant: 256
|
||||
maxObjectDepth: 4
|
||||
maxStrSize: 4096
|
||||
name: xcodemap-filter
|
||||
openMainWindow: true
|
||||
recordMode: manual
|
||||
sourceDisplayConfig:
|
||||
color: blue
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package work.slhaf.partner.api.agent;
|
||||
|
||||
import work.slhaf.partner.api.agent.exception.AgentLaunchFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.AgentRegisterFactory;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.flow.AgentInteraction;
|
||||
import work.slhaf.partner.api.agent.flow.entity.InteractionFlowContext;
|
||||
import work.slhaf.partner.api.agent.flow.AgentRunningFlow;
|
||||
import work.slhaf.partner.api.agent.flow.entity.RunningFlowContext;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentExceptionCallback;
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentLaunchFailedException;
|
||||
import work.slhaf.partner.api.agent.runtime.exception.GlobalExceptionHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -18,14 +21,14 @@ public class Agent {
|
||||
|
||||
private final List<Runnable> runners = new ArrayList<>();
|
||||
private final Class<?> applicationClass;
|
||||
private final InteractionFlowContext interactionContext;
|
||||
private final RunningFlowContext interactionContext;
|
||||
|
||||
private Agent(Class<?> clazz, InteractionFlowContext interactionContext) {
|
||||
private Agent(Class<?> clazz, RunningFlowContext interactionContext) {
|
||||
this.applicationClass = clazz;
|
||||
this.interactionContext = interactionContext;
|
||||
}
|
||||
|
||||
public static Agent newAgent(Class<?> clazz, InteractionFlowContext interactionContext) {
|
||||
public static Agent newAgent(Class<?> clazz, RunningFlowContext interactionContext) {
|
||||
if (clazz == null || interactionContext == null) {
|
||||
throw new AgentLaunchFailedException("Agent class 和 interaction flow context 不能为 null");
|
||||
}
|
||||
@@ -34,7 +37,7 @@ public class Agent {
|
||||
|
||||
public void run() {
|
||||
List<MetaModule> moduleList = AgentRegisterFactory.launch(applicationClass.getPackage().getName());
|
||||
AgentInteraction.launch(moduleList, interactionContext);
|
||||
AgentRunningFlow.launch(moduleList, interactionContext);
|
||||
launchRunners();
|
||||
}
|
||||
|
||||
@@ -50,4 +53,25 @@ public class Agent {
|
||||
runners.addAll(List.of(runnable));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent setAgentConfigManager(AgentConfigManager agentConfigManager) {
|
||||
AgentConfigManager.setINSTANCE(agentConfigManager);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent setAgentExceptionCallback(AgentExceptionCallback agentExceptionCallback){
|
||||
GlobalExceptionHandler.setExceptionCallback(agentExceptionCallback);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent addScanPackage(String packageName) {
|
||||
AgentRegisterFactory.addScanPackage(packageName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent addScanDir(String externalPackagePath) {
|
||||
AgentRegisterFactory.addScanDir(externalPackagePath);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import work.slhaf.partner.api.agent.factory.module.ModuleInitHookExecuteFactory;
|
||||
import work.slhaf.partner.api.agent.factory.module.ModuleProxyFactory;
|
||||
import work.slhaf.partner.api.agent.factory.module.ModuleRegisterFactory;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
@@ -45,12 +46,14 @@ public class AgentRegisterFactory {
|
||||
//. 执行模块PreHook逻辑
|
||||
new ModuleInitHookExecuteFactory().execute(registerContext);
|
||||
|
||||
return registerContext.getModuleFactoryContext().getModuleList();
|
||||
List<MetaModule> moduleList = registerContext.getModuleFactoryContext().getModuleList();
|
||||
return AgentConfigManager.INSTANCE.moduleEnabledStatusFilter(moduleList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加可扫描包
|
||||
*
|
||||
* @param packageName 指定的包名
|
||||
*/
|
||||
public static void addScanPackage(String packageName) {
|
||||
@@ -59,6 +62,7 @@ public class AgentRegisterFactory {
|
||||
|
||||
/**
|
||||
* 添加外部模块目录
|
||||
*
|
||||
* @param externalPackagePath 指定的外部模块目录路径
|
||||
*/
|
||||
public static void addScanDir(String externalPackagePath) {
|
||||
@@ -67,7 +71,11 @@ public class AgentRegisterFactory {
|
||||
throw new ExternalModulePathNotExistException("不存在的外部模块目录: " + externalPackagePath);
|
||||
}
|
||||
try {
|
||||
for (File f : file.listFiles()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
throw new ExternalModulePathNotExistException("外部模块目录为空: " + externalPackagePath);
|
||||
}
|
||||
for (File f : files) {
|
||||
if (f.getName().endsWith(".jar")) {
|
||||
urls.add(f.toURI().toURL());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package work.slhaf.partner.api.agent.factory.capability.exception;
|
||||
|
||||
public class CapabilityCheckFailedException extends RuntimeException {
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentLaunchFailedException;
|
||||
|
||||
public class CapabilityCheckFailedException extends AgentLaunchFailedException {
|
||||
public CapabilityCheckFailedException(String message) {
|
||||
super("Capability注册失败: " + message);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package work.slhaf.partner.api.agent.factory.capability.exception;
|
||||
|
||||
public class CapabilityFactoryExecuteFailedException extends RuntimeException {
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentLaunchFailedException;
|
||||
|
||||
public class CapabilityFactoryExecuteFailedException extends AgentLaunchFailedException {
|
||||
public CapabilityFactoryExecuteFailedException(String message) {
|
||||
super("CapabilityRegisterFactory 执行失败: " + message);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.ConfigFactoryContext;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.agent.runtime.config.DefaultAgentConfigManager;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -12,8 +14,7 @@ import java.util.List;
|
||||
|
||||
public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
|
||||
@Setter
|
||||
private static ModelConfigManager modelConfigManager = new DefaultModelConfigManager();
|
||||
private AgentConfigManager agentConfigManager;
|
||||
private HashMap<String, ModelConfig> modelConfigMap;
|
||||
private HashMap<String, List<Message>> modelPromptMap;
|
||||
|
||||
@@ -22,14 +23,20 @@ public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
ConfigFactoryContext factoryContext = context.getConfigFactoryContext();
|
||||
modelConfigMap = factoryContext.getModelConfigMap();
|
||||
modelPromptMap = factoryContext.getModelPromptMap();
|
||||
|
||||
if (AgentConfigManager.INSTANCE == null){
|
||||
AgentConfigManager.setINSTANCE(new DefaultAgentConfigManager());
|
||||
}
|
||||
|
||||
agentConfigManager = AgentConfigManager.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
modelConfigManager.load();
|
||||
modelConfigManager.check();
|
||||
modelConfigMap.putAll(modelConfigManager.getModelConfigMap());
|
||||
modelPromptMap.putAll(modelConfigManager.getModelPromptMap());
|
||||
agentConfigManager.load();
|
||||
agentConfigManager.check();
|
||||
modelConfigMap.putAll(agentConfigManager.getModelConfigMap());
|
||||
modelPromptMap.putAll(agentConfigManager.getModelPromptMap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ModelConfigDirNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ModelConfigNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ModelPromptDirNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ModelPromptNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.PrimaryModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.PrimaryModelPrompt;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 默认配置工厂
|
||||
* 将从当前运行目录的config文件夹下创建并读取配置
|
||||
*/
|
||||
public class DefaultModelConfigManager extends ModelConfigManager {
|
||||
|
||||
private static final String MODEL_CONFIG_DIR = "./config/model/";
|
||||
private static final String PROMPT_CONFIG_DIR = "./config/prompt/";
|
||||
|
||||
|
||||
@Override
|
||||
protected HashMap<String, List<Message>> loadPrompt() {
|
||||
File file = new File(PROMPT_CONFIG_DIR);
|
||||
if (!file.exists() && !file.isDirectory()) {
|
||||
throw new ModelPromptDirNotExistException("未找到提示词目录: " + PROMPT_CONFIG_DIR + " 请手动创建!");
|
||||
}
|
||||
File[] files = file.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
throw new ModelPromptNotExistException("在目录 " + PROMPT_CONFIG_DIR + " 中未找到提示词配置!");
|
||||
}
|
||||
HashMap<String, List<Message>> promptMap = new HashMap<>();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
PrimaryModelPrompt primaryModelPrompt = JSONUtil.readJSONObject(f, StandardCharsets.UTF_8).toBean(PrimaryModelPrompt.class);
|
||||
promptMap.put(primaryModelPrompt.getKey(), primaryModelPrompt.getMessages());
|
||||
}
|
||||
return promptMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HashMap<String, ModelConfig> loadConfig() {
|
||||
File file = new File(MODEL_CONFIG_DIR);
|
||||
if (!file.exists() || !file.isDirectory()) {
|
||||
throw new ModelConfigDirNotExistException("未找到配置目录: " + MODEL_CONFIG_DIR + " 请手动创建!");
|
||||
}
|
||||
File[] files = file.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
throw new ModelConfigNotExistException("在目录" + 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;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ModelConfigNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ModelPromptNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
public abstract class ModelConfigManager {
|
||||
|
||||
public static ModelConfigManager INSTANCE;
|
||||
@Getter
|
||||
protected HashMap<String, ModelConfig> modelConfigMap;
|
||||
@Getter
|
||||
protected HashMap<String, List<Message>> modelPromptMap;
|
||||
|
||||
protected ModelConfigManager() {
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
modelConfigMap = loadConfig();
|
||||
modelPromptMap = loadPrompt();
|
||||
}
|
||||
|
||||
protected abstract HashMap<String, List<Message>> loadPrompt();
|
||||
|
||||
protected abstract HashMap<String, ModelConfig> loadConfig();
|
||||
|
||||
/**
|
||||
* 对模型Config与Prompt分别进行检验,除了都必须包含default外,还需要确保数量、key一致,毕竟是模型配置与提示词
|
||||
*/
|
||||
public void check(){
|
||||
log.info("[ModelConfigManager]: 执行config与prompt检测...");
|
||||
if (!modelConfigMap.containsKey("default")){
|
||||
throw new ModelConfigNotExistException("缺少默认配置! 需确保存在一个模型配置的key为`default`");
|
||||
}
|
||||
if (!modelPromptMap.containsKey("basic")){
|
||||
throw new ModelPromptNotExistException("缺少基础Prompt! 需要确保存在key为basic的Prompt文件,它将与其他Prompt共同作用于模块节点。");
|
||||
}
|
||||
Set<String> configKeySet = new HashSet<>(modelConfigMap.keySet());
|
||||
configKeySet.remove("default");
|
||||
Set<String> promptKeySet = new HashSet<>(modelPromptMap.keySet());
|
||||
promptKeySet.remove("basic");
|
||||
if (!promptKeySet.containsAll(configKeySet)){
|
||||
log.warn("存在未被提示词包含的模型配置,该配置将无法生效!");
|
||||
}
|
||||
log.info("[ModelConfigManager]: 检测完毕.");
|
||||
}
|
||||
|
||||
|
||||
public List<Message> loadModelPrompt(String modelKey){
|
||||
if (!modelPromptMap.containsKey(modelKey)){
|
||||
throw new ModelPromptNotExistException("不存在的modelPrompt: "+modelKey);
|
||||
}
|
||||
return modelPromptMap.get(modelKey);
|
||||
}
|
||||
|
||||
public ModelConfig loadModelConfig(String modelKey) {
|
||||
if (!modelConfigMap.containsKey(modelKey)) {
|
||||
throw new ModelConfigNotExistException("不存在的modelKey: " + modelKey);
|
||||
}
|
||||
return modelConfigMap.get(modelKey);
|
||||
}
|
||||
|
||||
public void updateModelConfig(String modelKey, ModelConfig config) {
|
||||
if (!modelConfigMap.containsKey(modelKey)) {
|
||||
throw new ModelConfigNotExistException("不存在的modelKey: " + modelKey);
|
||||
}
|
||||
modelConfigMap.get(modelKey).setModel(config.getModel());
|
||||
modelConfigMap.get(modelKey).setBaseUrl(config.getBaseUrl());
|
||||
modelConfigMap.get(modelKey).setApikey(config.getApikey());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ConfigDirNotExistException extends ConfigFactoryInitFailedException {
|
||||
public ConfigDirNotExistException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ConfigDirNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentLaunchFailedException;
|
||||
|
||||
public class ConfigFactoryInitFailedException extends AgentLaunchFailedException {
|
||||
public ConfigFactoryInitFailedException(String message, Throwable cause) {
|
||||
super("AgentConfigManager 执行失败: " + message, cause);
|
||||
}
|
||||
|
||||
public ConfigFactoryInitFailedException(String message) {
|
||||
super("AgentConfigManager 执行失败: " + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException;
|
||||
|
||||
public class ConfigFactoryRuntimeException extends AgentRuntimeException {
|
||||
public ConfigFactoryRuntimeException(String message, Throwable cause) {
|
||||
super("ConfigFactory 运行出错: " + message, cause);
|
||||
}
|
||||
|
||||
public ConfigFactoryRuntimeException(String message) {
|
||||
super("ConfigFactory 运行出错: " + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ConfigGenerateFailedException extends ConfigFactoryInitFailedException {
|
||||
public ConfigGenerateFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ConfigGenerateFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ConfigNotExistException extends ConfigFactoryInitFailedException {
|
||||
public ConfigNotExistException(String message, Throwable e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
public ConfigNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ConfigUpdateFailedException extends ConfigFactoryRuntimeException{
|
||||
public ConfigUpdateFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ConfigUpdateFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ModelConfigDirNotExistException extends ModelConfigFactoryFailedException{
|
||||
public ModelConfigDirNotExistException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ModelConfigDirNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ModelConfigFactoryFailedException extends RuntimeException {
|
||||
public ModelConfigFactoryFailedException(String message, Throwable cause) {
|
||||
super("ModelConfigManager 执行失败: " + message, cause);
|
||||
}
|
||||
|
||||
public ModelConfigFactoryFailedException(String message) {
|
||||
super("ModelConfigManager 执行失败: " + message);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ModelConfigNotExistException extends ModelConfigFactoryFailedException {
|
||||
public ModelConfigNotExistException(String message, Throwable e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
public ModelConfigNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ModelPromptDirNotExistException extends ModelConfigFactoryFailedException{
|
||||
public ModelPromptDirNotExistException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ModelPromptDirNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class ModelPromptNotExistException extends ModelConfigFactoryFailedException{
|
||||
public ModelPromptNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ModelPromptNotExistException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class PromptDirNotExistException extends ConfigFactoryInitFailedException {
|
||||
public PromptDirNotExistException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public PromptDirNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.config.exception;
|
||||
|
||||
public class PromptNotExistException extends ConfigFactoryInitFailedException {
|
||||
public PromptNotExistException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PromptNotExistException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package work.slhaf.partner.api.agent.factory.module;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import org.reflections.Reflections;
|
||||
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.config.ModelConfigManager;
|
||||
import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AfterExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
@@ -11,8 +10,9 @@ import work.slhaf.partner.api.agent.factory.module.annotation.BeforeExecute;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ModuleCheckException;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
@@ -59,7 +59,7 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
ActivateModel instance = type.getConstructor().newInstance();
|
||||
modelKeySet.add(instance.modelKey());
|
||||
}
|
||||
Set<String> promptKeySet = ModelConfigManager.INSTANCE.getModelPromptMap().keySet();
|
||||
Set<String> promptKeySet = AgentConfigManager.INSTANCE.getModelPromptMap().keySet();
|
||||
if (!promptKeySet.containsAll(modelKeySet)) {
|
||||
modelKeySet.removeAll(promptKeySet);
|
||||
throw new ModuleCheckException("存在未配置Prompt的ActivateModel实现! 缺少Prompt的ModelKey列表: " + modelKeySet);
|
||||
@@ -116,10 +116,10 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
|
||||
private void checkLocation(Set<Class<?>> types) {
|
||||
for (Class<?> type : types) {
|
||||
if (AgentInteractionModule.class.isAssignableFrom(type)) {
|
||||
if (AgentRunningModule.class.isAssignableFrom(type)) {
|
||||
continue;
|
||||
}
|
||||
if (AgentInteractionSubModule.class.isAssignableFrom(type)) {
|
||||
if (AgentRunningSubModule.class.isAssignableFrom(type)) {
|
||||
continue;
|
||||
}
|
||||
if (ActivateModel.class.isAssignableFrom(type)) {
|
||||
@@ -134,7 +134,7 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
if (type.isAnnotation()) {
|
||||
continue;
|
||||
}
|
||||
if (type.isAssignableFrom(AgentInteractionModule.class)) {
|
||||
if (type.isAssignableFrom(AgentRunningModule.class)) {
|
||||
continue;
|
||||
}
|
||||
throw new ModuleCheckException("存在未继承AgentInteractionModule.class的AgentModule实现: " + type.getSimpleName());
|
||||
|
||||
@@ -7,7 +7,7 @@ import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ModuleInitHookExecuteFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaMethod;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningModule;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
@@ -52,7 +52,7 @@ public class ModuleInitHookExecuteFactory extends AgentBaseFactory {
|
||||
}
|
||||
|
||||
private List<MetaMethod> collectInitHookMethods(Class<?> clazz) {
|
||||
Set<Class<?>> classes = collectExtendedClasses(clazz, AgentInteractionModule.class);
|
||||
Set<Class<?>> classes = collectExtendedClasses(clazz, AgentRunningModule.class);
|
||||
return classes.stream()
|
||||
.map(Class::getDeclaredMethods)
|
||||
.flatMap(Arrays::stream)
|
||||
|
||||
@@ -13,7 +13,7 @@ import work.slhaf.partner.api.agent.factory.module.exception.ModuleInstanceGener
|
||||
import work.slhaf.partner.api.agent.factory.module.exception.ModuleProxyGenerateFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaMethod;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningModule;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -60,7 +60,7 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
Class<?> clazz = metaModule.getClazz();
|
||||
Class<?> proxyClass = new ByteBuddy()
|
||||
.subclass(clazz)
|
||||
.method(ElementMatchers.isOverriddenFrom(AgentInteractionModule.class))
|
||||
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
|
||||
.intercept(MethodDelegation.to(new ModuleProxyInterceptor(record.post, record.pre)))
|
||||
.make()
|
||||
.load(ModuleProxyFactory.class.getClassLoader())
|
||||
@@ -77,7 +77,7 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
//获取该类本身的hook逻辑
|
||||
collectHookMethods(post, pre, clazz);
|
||||
//获取它所继承、实现的抽象类或接口, 以AgentInteractionModule、ActiveModel为终点
|
||||
Set<Class<?>> classes = collectExtendedClasses(clazz, AgentInteractionModule.class);
|
||||
Set<Class<?>> classes = collectExtendedClasses(clazz, AgentRunningModule.class);
|
||||
//获取这些类中的hook逻辑
|
||||
collectHookMethods(post, pre, classes);
|
||||
return new MethodsListRecord(post, pre);
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
||||
* 仅适用于以下类中的方法:
|
||||
* 1. <code>@AgentModule</code>注解所在类
|
||||
* 2. <code>ActivateModel</code>子类
|
||||
* 3. <code>AgentInteractionModule</code>或者<code>AgentInteractionSubModule</code>子类
|
||||
* 3. <code>AgentRunningModule</code>或者<code>AgentRunningSubModule</code>子类
|
||||
*/
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.lang.annotation.Target;
|
||||
* 仅适用于以下类中的方法:
|
||||
* 1. <code>@AgentModule</code>注解所在类
|
||||
* 2. <code>ActivateModel</code>子类
|
||||
* 3. <code>AgentInteractionModule</code>或者<code>AgentInteractionSubModule</code>子类
|
||||
* 3. <code>AgentRunningModule</code>或者<code>AgentRunningSubModule</code>子类
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
public class ModuleCheckException extends ModuleFactoryFailedException{
|
||||
public class ModuleCheckException extends ModuleFactoryInitFailedException {
|
||||
public ModuleCheckException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
public class ModuleFactoryFailedException extends RuntimeException {
|
||||
public ModuleFactoryFailedException(String message) {
|
||||
super("ModuleFactory 执行失败: "+message);
|
||||
}
|
||||
|
||||
public ModuleFactoryFailedException(String message, Throwable cause) {
|
||||
super("ModuleFactory 执行失败: "+message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
public class ModuleFactoryInitFailedException extends RuntimeException {
|
||||
public ModuleFactoryInitFailedException(String message) {
|
||||
super("ModuleFactory 执行失败: "+message);
|
||||
}
|
||||
|
||||
public ModuleFactoryInitFailedException(String message, Throwable cause) {
|
||||
super("ModuleFactory 执行失败: "+message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
public class ModuleInitHookExecuteFailedException extends ModuleFactoryFailedException{
|
||||
public class ModuleInitHookExecuteFailedException extends ModuleFactoryInitFailedException {
|
||||
public ModuleInitHookExecuteFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
public class ModuleInstanceGenerateFailedException extends ModuleFactoryFailedException{
|
||||
public class ModuleInstanceGenerateFailedException extends ModuleFactoryInitFailedException {
|
||||
public ModuleInstanceGenerateFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.exception;
|
||||
|
||||
public class ModuleProxyGenerateFailedException extends ModuleFactoryFailedException{
|
||||
public class ModuleProxyGenerateFailedException extends ModuleFactoryInitFailedException {
|
||||
public ModuleProxyGenerateFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -8,4 +8,5 @@ public class MetaModule {
|
||||
private int order;
|
||||
private Class<?> clazz;
|
||||
private Object instance;
|
||||
private boolean enabled = true;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.flow;
|
||||
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.flow.entity.InteractionFlowContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Agent执行流程
|
||||
*/
|
||||
public class AgentInteraction {
|
||||
|
||||
private AgentInteraction(){}
|
||||
|
||||
public static void launch(List<MetaModule> moduleList, InteractionFlowContext interactionContext){
|
||||
//流程执行启动,需考虑模块热插拔,可结合http调整模块启用情况,并序列化至本地或数据库中
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package work.slhaf.partner.api.agent.flow;
|
||||
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.flow.entity.RunningFlowContext;
|
||||
import work.slhaf.partner.api.agent.runtime.exception.GlobalExceptionHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Agent执行流程
|
||||
*/
|
||||
public class AgentRunningFlow {
|
||||
|
||||
private AgentRunningFlow(){}
|
||||
|
||||
public static void launch(List<MetaModule> moduleList, RunningFlowContext interactionContext){
|
||||
try {
|
||||
//流程执行启动,需考虑模块热插拔,可结合http调整模块启用情况,并序列化至本地或数据库中
|
||||
}catch (Exception e){
|
||||
GlobalExceptionHandler.INSTANCE.handle(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package work.slhaf.partner.api.agent.flow.abstracts;
|
||||
|
||||
import work.slhaf.partner.api.agent.factory.config.ModelConfigManager;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.flow.entity.Model;
|
||||
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
|
||||
import work.slhaf.partner.api.chat.ChatClient;
|
||||
import work.slhaf.partner.api.chat.constant.ChatConstant;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
@@ -14,24 +15,29 @@ import java.util.List;
|
||||
|
||||
public interface ActivateModel {
|
||||
|
||||
ModelConfigManager modelConfigManager = ModelConfigManager.INSTANCE;
|
||||
AgentConfigManager AGENT_CONFIG_MANAGER = AgentConfigManager.INSTANCE;
|
||||
|
||||
@Init
|
||||
default void modelSettings() {
|
||||
Model model = new Model();
|
||||
ModelConfig modelConfig = ModelConfigManager.INSTANCE.loadModelConfig(modelKey());
|
||||
ModelConfig modelConfig = AgentConfigManager.INSTANCE.loadModelConfig(modelKey());
|
||||
model.setBaseMessages(withBasicPrompt() ? loadSpecificPromptAndBasicPrompt(modelKey()) : loadSpecificPrompt(modelKey()));
|
||||
model.setChatClient(new ChatClient(modelConfig.getBaseUrl(), modelConfig.getApikey(), modelConfig.getModel()));
|
||||
((Module) this).setModel(model);
|
||||
}
|
||||
|
||||
default void updateModelSettings(ChatClient newChatClient) {
|
||||
BeanUtil.copyProperties(newChatClient, chatClient());
|
||||
}
|
||||
|
||||
private List<Message> loadSpecificPrompt(String modelKey) {
|
||||
return modelConfigManager.loadModelPrompt(modelKey);
|
||||
return AGENT_CONFIG_MANAGER.loadModelPrompt(modelKey);
|
||||
}
|
||||
|
||||
private List<Message> loadSpecificPromptAndBasicPrompt(String modelKey) {
|
||||
List<Message> messages = new ArrayList<>();
|
||||
messages.addAll(modelConfigManager.loadModelPrompt("basic"));
|
||||
messages.addAll(modelConfigManager.loadModelPrompt(modelKey));
|
||||
messages.addAll(AGENT_CONFIG_MANAGER.loadModelPrompt("basic"));
|
||||
messages.addAll(AGENT_CONFIG_MANAGER.loadModelPrompt(modelKey));
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package work.slhaf.partner.api.agent.flow.abstracts;
|
||||
|
||||
import work.slhaf.partner.api.agent.flow.entity.InteractionFlowContext;
|
||||
|
||||
/**
|
||||
* 流程执行模块基类
|
||||
*/
|
||||
public abstract class AgentInteractionModule extends Module {
|
||||
public abstract void execute(InteractionFlowContext context);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package work.slhaf.partner.api.agent.flow.abstracts;
|
||||
|
||||
import work.slhaf.partner.api.agent.flow.entity.RunningFlowContext;
|
||||
|
||||
/**
|
||||
* 流程执行模块基类
|
||||
*/
|
||||
public abstract class AgentRunningModule extends Module {
|
||||
public abstract void execute(RunningFlowContext context);
|
||||
}
|
||||
@@ -6,7 +6,7 @@ package work.slhaf.partner.api.agent.flow.abstracts;
|
||||
* @param <I> 输入类型
|
||||
* @param <O> 输出类型
|
||||
*/
|
||||
public abstract class AgentInteractionSubModule<I, O> extends Module {
|
||||
public abstract class AgentRunningSubModule<I, O> extends Module {
|
||||
|
||||
public abstract O execute(I data);
|
||||
|
||||
@@ -6,6 +6,6 @@ import lombok.Data;
|
||||
* 流程上下文
|
||||
*/
|
||||
@Data
|
||||
public abstract class InteractionFlowContext {
|
||||
public abstract class RunningFlowContext {
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package work.slhaf.partner.api.agent.entity;
|
||||
package work.slhaf.partner.api.agent.runtime;
|
||||
|
||||
import lombok.Data;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
@@ -0,0 +1,125 @@
|
||||
package work.slhaf.partner.api.agent.runtime.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ConfigNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ConfigUpdateFailedException;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.PromptNotExistException;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Slf4j
|
||||
public abstract class AgentConfigManager {
|
||||
|
||||
@Setter
|
||||
public static AgentConfigManager INSTANCE;
|
||||
private static final String DEFAULT_KEY = "default";
|
||||
|
||||
@Getter
|
||||
protected HashMap<String, ModelConfig> modelConfigMap;
|
||||
@Getter
|
||||
protected HashMap<String, List<Message>> modelPromptMap;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
protected HashMap<String, Boolean> moduleEnabledStatus;
|
||||
|
||||
protected List<MetaModule> moduleList;
|
||||
|
||||
public void load() {
|
||||
modelConfigMap = loadModelConfig();
|
||||
modelPromptMap = loadModelPrompt();
|
||||
}
|
||||
|
||||
protected abstract HashMap<String, List<Message>> loadModelPrompt();
|
||||
|
||||
protected abstract HashMap<String, ModelConfig> loadModelConfig();
|
||||
|
||||
public abstract void dumpModelConfig(String key);
|
||||
|
||||
protected abstract void dumpModuleEnabledStatus();
|
||||
|
||||
protected abstract HashMap<String, Boolean> loadModuleEnabledStatusMap();
|
||||
|
||||
public List<MetaModule> moduleEnabledStatusFilter(List<MetaModule> moduleList) {
|
||||
this.moduleList = moduleList;
|
||||
this.moduleEnabledStatus = loadModuleEnabledStatusMap();
|
||||
|
||||
boolean unmatch = false;
|
||||
for (MetaModule metaModule : moduleList) {
|
||||
String moduleName = metaModule.getName();
|
||||
if (moduleEnabledStatus.containsKey(moduleName)) {
|
||||
metaModule.setEnabled(moduleEnabledStatus.get(moduleName));
|
||||
} else {
|
||||
log.warn("缺少Module {} 启用配置! 将触发更新操作!", moduleName);
|
||||
unmatch = true;
|
||||
}
|
||||
}
|
||||
if (unmatch) {
|
||||
dumpModuleEnabledStatus();
|
||||
}
|
||||
return moduleList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对模型Config与Prompt分别进行检验,除了都必须包含default外,还需要确保数量、key一致,毕竟是模型配置与提示词
|
||||
*/
|
||||
public void check() {
|
||||
log.info("[AgentConfigManager]: 执行config与prompt检测...");
|
||||
if (!modelConfigMap.containsKey("default")) {
|
||||
throw new ConfigNotExistException("缺少默认配置! 需确保存在一个模型配置的key为`default`");
|
||||
}
|
||||
if (!modelPromptMap.containsKey("basic")) {
|
||||
throw new PromptNotExistException("缺少基础Prompt! 需要确保存在key为basic的Prompt文件,它将与其他Prompt共同作用于模块节点。");
|
||||
}
|
||||
Set<String> configKeySet = new HashSet<>(modelConfigMap.keySet());
|
||||
configKeySet.remove("default");
|
||||
Set<String> promptKeySet = new HashSet<>(modelPromptMap.keySet());
|
||||
promptKeySet.remove("basic");
|
||||
if (!promptKeySet.containsAll(configKeySet)) {
|
||||
log.warn("存在未被提示词包含的模型配置,该配置将无法生效!");
|
||||
}
|
||||
log.info("[AgentConfigManager]: 检测完毕.");
|
||||
}
|
||||
|
||||
public List<Message> loadModelPrompt(String modelKey) {
|
||||
if (!modelPromptMap.containsKey(modelKey)) {
|
||||
throw new PromptNotExistException("不存在的modelPrompt: " + modelKey);
|
||||
}
|
||||
return modelPromptMap.get(modelKey);
|
||||
}
|
||||
|
||||
public ModelConfig loadModelConfig(String modelKey) {
|
||||
if (!modelConfigMap.containsKey(modelKey)) {
|
||||
return modelConfigMap.get(DEFAULT_KEY);
|
||||
}
|
||||
return modelConfigMap.get(modelKey);
|
||||
}
|
||||
|
||||
public void updateModelConfig(String modelKey, ModelConfig config) {
|
||||
modelConfigMap.put(modelKey, config);
|
||||
dumpModelConfig(modelKey);
|
||||
}
|
||||
|
||||
public void updateModuleEnabledStatus(String key, boolean status) {
|
||||
if (!moduleEnabledStatus.containsKey(key)) {
|
||||
throw new ConfigUpdateFailedException("模块状态更新失败! 不存在的ModuleKey: " + key);
|
||||
}
|
||||
moduleEnabledStatus.put(key, status);
|
||||
dumpModuleEnabledStatus();
|
||||
for (MetaModule metaModule : moduleList) {
|
||||
if (metaModule.getName().equals(key)) {
|
||||
metaModule.setEnabled(status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package work.slhaf.partner.api.agent.runtime.config;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.*;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.ModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.PrimaryModelConfig;
|
||||
import work.slhaf.partner.api.agent.factory.config.pojo.PrimaryModelPrompt;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 默认配置工厂
|
||||
* 将从当前运行目录的config文件夹下创建并读取配置
|
||||
*/
|
||||
@Slf4j
|
||||
public class DefaultAgentConfigManager extends AgentConfigManager {
|
||||
|
||||
private static final String CONFIG_DIR = "./config/";
|
||||
private static final String MODEL_CONFIG_DIR = "./config/model/";
|
||||
private static final String PROMPT_CONFIG_DIR = "./config/prompt/";
|
||||
private static final String MODULE_ENABLED_STATUS_CONFIG_FILE = CONFIG_DIR + "module_enabled_status.json";
|
||||
|
||||
|
||||
@Override
|
||||
protected HashMap<String, List<Message>> loadModelPrompt() {
|
||||
File file = new File(PROMPT_CONFIG_DIR);
|
||||
if (!file.exists() && !file.isDirectory()) {
|
||||
throw new PromptDirNotExistException("未找到提示词目录: " + PROMPT_CONFIG_DIR + " 请手动创建!");
|
||||
}
|
||||
File[] files = file.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
throw new PromptNotExistException("在目录 " + PROMPT_CONFIG_DIR + " 中未找到提示词配置!");
|
||||
}
|
||||
HashMap<String, List<Message>> promptMap = new HashMap<>();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
PrimaryModelPrompt primaryModelPrompt = JSONUtil.readJSONObject(f, StandardCharsets.UTF_8).toBean(PrimaryModelPrompt.class);
|
||||
promptMap.put(primaryModelPrompt.getKey(), primaryModelPrompt.getMessages());
|
||||
}
|
||||
return promptMap;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HashMap<String, Boolean> loadModuleEnabledStatusMap() {
|
||||
File file = new File(MODULE_ENABLED_STATUS_CONFIG_FILE);
|
||||
try {
|
||||
HashMap<String, Boolean> moduleEnabledStatus = new HashMap<>();
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
for (MetaModule module : moduleList) {
|
||||
moduleEnabledStatus.put(module.getName(), module.isEnabled());
|
||||
}
|
||||
dumpModuleEnabledStatus();
|
||||
} else {
|
||||
JSONObject obj = JSONUtil.readJSONObject(file, StandardCharsets.UTF_8);
|
||||
for (String s : obj.keySet()) {
|
||||
moduleEnabledStatus.put(s, obj.getBool(s));
|
||||
}
|
||||
log.info("ModuleEnabledStatusConfig 配置文件已成功读取!");
|
||||
}
|
||||
return moduleEnabledStatus;
|
||||
} catch (Exception e) {
|
||||
throw new ConfigGenerateFailedException("ModuleEnabledStatusConfig 配置文件创建失败!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpModelConfig(String key) {
|
||||
try {
|
||||
File file = new File(MODEL_CONFIG_DIR + key + ".json");
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
FileUtils.writeStringToFile(file, JSONUtil.toJsonPrettyStr(modelConfigMap.get(key)), StandardCharsets.UTF_8, false);
|
||||
} catch (Exception e) {
|
||||
throw new ConfigUpdateFailedException("ModelConfig 配置文件更新失败!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dumpModuleEnabledStatus() {
|
||||
try {
|
||||
File file = new File(MODULE_ENABLED_STATUS_CONFIG_FILE);
|
||||
FileUtils.writeStringToFile(file, JSONUtil.toJsonPrettyStr(moduleEnabledStatus), StandardCharsets.UTF_8, false);
|
||||
} catch (IOException e) {
|
||||
throw new ConfigGenerateFailedException("ModuleEnabledStatus 配置文件更新失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package work.slhaf.partner.api.agent.runtime.exception;
|
||||
|
||||
public interface AgentExceptionCallback {
|
||||
void onRuntimeException(AgentRuntimeException e);
|
||||
void onFailedException(AgentLaunchFailedException e);
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.exception;
|
||||
package work.slhaf.partner.api.agent.runtime.exception;
|
||||
|
||||
public class AgentLaunchFailedException extends RuntimeException {
|
||||
public AgentLaunchFailedException(String message, Throwable cause) {
|
||||
super("Agent 启动失败: " + message, cause);
|
||||
super("Agent 启动失败 " + message, cause);
|
||||
}
|
||||
|
||||
public AgentLaunchFailedException(String message) {
|
||||
super("Agent 启动失败: " + message);
|
||||
super("Agent 启动失败 " + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package work.slhaf.partner.api.agent.runtime.exception;
|
||||
|
||||
public class AgentRuntimeException extends RuntimeException {
|
||||
public AgentRuntimeException(String message) {
|
||||
super("Agent 执行出错 " + message);
|
||||
}
|
||||
|
||||
public AgentRuntimeException(String message, Throwable cause) {
|
||||
super("Agent 执行出错 " + message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package work.slhaf.partner.api.agent.runtime.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class DefaultAgentExceptionCallback implements AgentExceptionCallback {
|
||||
|
||||
@Override
|
||||
public void onRuntimeException(AgentRuntimeException e) {
|
||||
log.error("Agent 运行异常: ", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailedException(AgentLaunchFailedException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package work.slhaf.partner.api.agent.runtime.exception;
|
||||
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
public static GlobalExceptionHandler INSTANCE = new GlobalExceptionHandler();
|
||||
|
||||
private AgentExceptionCallback exceptionCallback = new DefaultAgentExceptionCallback();
|
||||
|
||||
public void handle(Throwable e) {
|
||||
|
||||
switch (e.getClass().getSimpleName()) {
|
||||
case "AgentRuntimeException":
|
||||
exceptionCallback.onRuntimeException((AgentRuntimeException) e);
|
||||
break;
|
||||
case "AgentLaunchFailedException":
|
||||
exceptionCallback.onFailedException((AgentLaunchFailedException) e);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("未经处理的异常!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setExceptionCallback(AgentExceptionCallback callback) {
|
||||
INSTANCE.exceptionCallback = callback;
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,15 @@ import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.implementation.MethodDelegation;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningModule;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class ModuleProxyTest {
|
||||
@Test
|
||||
public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
Class<? extends AgentInteractionModule> clazz = new ByteBuddy().subclass(MyAgentInteractionModule.class)
|
||||
.method(ElementMatchers.isOverriddenFrom(AgentInteractionModule.class))
|
||||
Class<? extends AgentRunningModule> clazz = new ByteBuddy().subclass(MyAgentRunningModule.class)
|
||||
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
|
||||
.intercept(MethodDelegation.to(
|
||||
new MyModuleProxyInterceptor()
|
||||
))
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package module;
|
||||
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionModule;
|
||||
import work.slhaf.partner.api.agent.flow.entity.InteractionFlowContext;
|
||||
|
||||
public class MyAgentInteractionModule extends AgentInteractionModule {
|
||||
@Override
|
||||
public void execute(InteractionFlowContext context) {
|
||||
System.out.println("MyAgentInteractionModule");
|
||||
}
|
||||
}
|
||||
11
Partner-Api/src/test/java/module/MyAgentRunningModule.java
Normal file
11
Partner-Api/src/test/java/module/MyAgentRunningModule.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package module;
|
||||
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningModule;
|
||||
import work.slhaf.partner.api.agent.flow.entity.RunningFlowContext;
|
||||
|
||||
public class MyAgentRunningModule extends AgentRunningModule {
|
||||
@Override
|
||||
public void execute(RunningFlowContext context) {
|
||||
System.out.println("MyAgentRunningModule");
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
|
||||
import work.slhaf.partner.core.cognation.common.pojo.MemoryResult;
|
||||
import work.slhaf.partner.core.cognation.common.pojo.MemorySliceResult;
|
||||
@@ -30,7 +30,7 @@ import static work.slhaf.partner.common.util.ExtractUtil.extractJson;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
public class SliceSelectEvaluator extends AgentInteractionSubModule<EvaluatorInput, List<EvaluatedSlice>> implements ActivateModel {
|
||||
public class SliceSelectEvaluator extends AgentRunningSubModule<EvaluatorInput, List<EvaluatedSlice>> implements ActivateModel {
|
||||
private static volatile SliceSelectEvaluator sliceSelectEvaluator;
|
||||
private InteractionThreadPoolExecutor executor;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
import work.slhaf.partner.api.chat.pojo.MetaMessage;
|
||||
import work.slhaf.partner.common.exception_handler.GlobalExceptionHandler;
|
||||
@@ -31,7 +31,7 @@ import static work.slhaf.partner.common.util.ExtractUtil.fixTopicPath;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
public class MemorySelectExtractor extends AgentInteractionSubModule<InteractionContext, ExtractorResult> implements ActivateModel {
|
||||
public class MemorySelectExtractor extends AgentRunningSubModule<InteractionContext, ExtractorResult> implements ActivateModel {
|
||||
|
||||
private static volatile MemorySelectExtractor memorySelectExtractor;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package work.slhaf.partner.module.modules.memory.updater.summarizer;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
|
||||
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeInput;
|
||||
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeResult;
|
||||
@@ -13,7 +13,7 @@ import java.util.HashMap;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
public class MemorySummarizer extends AgentInteractionSubModule<SummarizeInput,SummarizeResult> {
|
||||
public class MemorySummarizer extends AgentRunningSubModule<SummarizeInput,SummarizeResult> {
|
||||
|
||||
private static volatile MemorySummarizer memorySummarizer;
|
||||
public static final String MODEL_KEY = "memory_summarizer";
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeInput;
|
||||
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeResult;
|
||||
@@ -20,7 +20,7 @@ import static work.slhaf.partner.common.util.ExtractUtil.fixTopicPath;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
public class MultiSummarizer extends AgentInteractionSubModule<SummarizeInput, SummarizeResult> implements ActivateModel {
|
||||
public class MultiSummarizer extends AgentRunningSubModule<SummarizeInput, SummarizeResult> implements ActivateModel {
|
||||
|
||||
private static volatile MultiSummarizer multiSummarizer;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.chat.constant.ChatConstant;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
@@ -20,7 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
@Data
|
||||
public class SingleSummarizer extends AgentInteractionSubModule<List<Message>,Void> implements ActivateModel {
|
||||
public class SingleSummarizer extends AgentRunningSubModule<List<Message>,Void> implements ActivateModel {
|
||||
|
||||
private static volatile SingleSummarizer singleSummarizer;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -16,7 +16,7 @@ import static work.slhaf.partner.common.util.ExtractUtil.extractJson;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
public class TotalSummarizer extends AgentInteractionSubModule<HashMap<String, String>, String> implements ActivateModel {
|
||||
public class TotalSummarizer extends AgentRunningSubModule<HashMap<String, String>, String> implements ActivateModel {
|
||||
|
||||
private static volatile TotalSummarizer totalSummarizer;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
import work.slhaf.partner.core.cognation.cognation.CognationCapability;
|
||||
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class RelationExtractor extends AgentInteractionSubModule<InteractionContext, RelationExtractResult> implements ActivateModel {
|
||||
public class RelationExtractor extends AgentRunningSubModule<InteractionContext, RelationExtractResult> implements ActivateModel {
|
||||
|
||||
private static volatile RelationExtractor relationExtractor;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentInteractionSubModule;
|
||||
import work.slhaf.partner.api.agent.flow.abstracts.AgentRunningSubModule;
|
||||
import work.slhaf.partner.api.chat.pojo.ChatResponse;
|
||||
import work.slhaf.partner.core.cognation.cognation.CognationCapability;
|
||||
import work.slhaf.partner.core.cognation.submodule.perceive.PerceiveCapability;
|
||||
@@ -18,7 +18,7 @@ import java.util.HashMap;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class StaticMemoryExtractor extends AgentInteractionSubModule<InteractionContext, HashMap<String, String>> implements ActivateModel {
|
||||
public class StaticMemoryExtractor extends AgentRunningSubModule<InteractionContext, HashMap<String, String>> implements ActivateModel {
|
||||
|
||||
private static volatile StaticMemoryExtractor staticMemoryExtractor;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package work.slhaf.demo.flow;
|
||||
|
||||
import work.slhaf.partner.api.agent.flow.entity.InteractionFlowContext;
|
||||
import work.slhaf.partner.api.agent.flow.entity.RunningFlowContext;
|
||||
|
||||
public class AgentDemoFlowContext extends InteractionFlowContext {
|
||||
public class AgentDemoFlowContext extends RunningFlowContext {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user