mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
进行 框架-主题 的适配测试,发现了一些问题并进行了修复
框架: - 去除了 ActivateModel 中 modelKey() 方法的默认实现,对于特殊的 AgentModule 继承者(CoreModule)而言,直接获取注解信息不可行,如果保持,则需要另加判断逻辑。这是没有必要的 - 发现 Agent 启动流程中,由于 Gateway 的启动可能依赖配置文件的加载,故将 AgentConfigManager 与 AgentGateway 的指定替换为类型指定,在合适的时机通过反射进行实例化 - 在 AgentUtil 中新增了链式判断指定类的注解链上是否存在指定注解的方法,目前用于 CapabilityHolder 的持有实例判定 - 发现 CapabilityFactoryContext 中 cores、capabilities 未赋值导致空指针异常,已修复 - 将 AgentConfigManager 中的检验逻辑进行抽离,放到了 ConfigLoaderFactory 中,避免职责混淆 - 发现 CoreModule 的注解使用错误,`@Retention(RetentionPolicy.RUNTIME)`元注解可以使得注解在代码运行时能够被反射扫描 - 在 ModuleCheckFactory 中添加了对于 Module 与 SubModule 的注解、继承使用是否匹配的检验 - 发现对于一个类来说,无法直接通过一层反射获取到‘注解的注解’,故在 ModuleRegisterFactory 中针对 CoreModule 的注册做了特殊处理 主体: - 发现一些类缺少必要注解,已修复 - 发现存在有些必要的类未公开化无参构造函数,已修复,并在框架部分增加校验逻辑 其他: - 由于项目的启动流程与完整的配置文件密不可分,所以开始尝试编写启动说明,目前只写了开头
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -36,8 +36,8 @@ build/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
/data/
|
||||
/config/
|
||||
/backup/data/
|
||||
/backup/config/
|
||||
/Partner-Core/src/main/java/src/test/java/memory/test.json
|
||||
/Partner-Core/src/main/java/src/test/java/memory/result/input1.json
|
||||
/Partner-Core/src/main/java/src/test/java/memory/result/input2.json
|
||||
@@ -51,3 +51,5 @@ build/
|
||||
/backup/
|
||||
/Partner-Main/src/test/java/text/test.json
|
||||
/CLAUDE.md
|
||||
/config/
|
||||
/data/
|
||||
|
||||
@@ -18,15 +18,19 @@ import java.util.concurrent.Executors;
|
||||
*/
|
||||
public final class Agent {
|
||||
|
||||
public static AgentGatewayStep newAgent(Class<?> clazz) {
|
||||
public static AgentConfigManagerStep newAgent(Class<?> clazz) {
|
||||
if (clazz == null) {
|
||||
throw new AgentLaunchFailedException("Agent class 和 interaction flow context 不能为 null");
|
||||
}
|
||||
return new AgentApp(clazz);
|
||||
}
|
||||
|
||||
public interface AgentConfigManagerStep {
|
||||
AgentGatewayStep setAgentConfigManager(Class<? extends AgentConfigManager> agentConfigManager);
|
||||
}
|
||||
|
||||
public interface AgentGatewayStep {
|
||||
AgentStep setGateway(AgentGateway gateway);
|
||||
AgentStep setGateway(Class<? extends AgentGateway> gateway);
|
||||
}
|
||||
|
||||
public interface AgentStep {
|
||||
@@ -34,9 +38,7 @@ public final class Agent {
|
||||
|
||||
AgentStep addAfterLaunchRunners(Runnable... runners);
|
||||
|
||||
AgentStep setAgentConfigManager(AgentConfigManager agentConfigManager);
|
||||
|
||||
AgentStep setAgentExceptionCallback(AgentExceptionCallback agentExceptionCallback);
|
||||
AgentStep setAgentExceptionCallback(Class<? extends AgentExceptionCallback> agentExceptionCallback);
|
||||
|
||||
AgentStep addScanPackage(String packageName);
|
||||
|
||||
@@ -46,21 +48,24 @@ public final class Agent {
|
||||
}
|
||||
|
||||
|
||||
public static class AgentApp implements AgentStep, AgentGatewayStep {
|
||||
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 AgentGateway gateway;
|
||||
private final Class<?> applicationClass;
|
||||
private Class<? extends AgentConfigManager> agentConfigManagerClass;
|
||||
private Class<? extends AgentGateway> gatewayClass;
|
||||
private Class<? extends AgentExceptionCallback> agentExceptionCallbackClass;
|
||||
|
||||
private AgentApp(Class<?> clazz) {
|
||||
this.applicationClass = clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentStep setGateway(AgentGateway gateway) {
|
||||
this.gateway = gateway;
|
||||
public AgentStep setGateway(Class<? extends AgentGateway> gateway) {
|
||||
this.gatewayClass = gateway;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -77,14 +82,14 @@ public final class Agent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentStep setAgentConfigManager(AgentConfigManager agentConfigManager) {
|
||||
AgentConfigManager.setINSTANCE(agentConfigManager);
|
||||
public AgentGatewayStep setAgentConfigManager(Class<? extends AgentConfigManager> agentConfigManager) {
|
||||
this.agentConfigManagerClass = agentConfigManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentStep setAgentExceptionCallback(AgentExceptionCallback agentExceptionCallback) {
|
||||
GlobalExceptionHandler.setExceptionCallback(agentExceptionCallback);
|
||||
public AgentStep setAgentExceptionCallback(Class<? extends AgentExceptionCallback> agentExceptionCallback) {
|
||||
agentExceptionCallbackClass = agentExceptionCallback;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -102,10 +107,29 @@ public final class Agent {
|
||||
|
||||
@Override
|
||||
public void launch() {
|
||||
launchRunners(beforeLaunchRunners);
|
||||
beforeLaunch();
|
||||
AgentRegisterFactory.launch(applicationClass.getPackageName());
|
||||
executorService.execute(() -> gateway.launch());
|
||||
launchRunners(afterLaunchRunners);
|
||||
afterLaunch();
|
||||
}
|
||||
|
||||
private void afterLaunch() {
|
||||
try {
|
||||
this.gateway = gatewayClass.getDeclaredConstructor().newInstance();
|
||||
executorService.execute(() -> gateway.launch());
|
||||
launchRunners(afterLaunchRunners);
|
||||
}catch (Exception e){
|
||||
throw new AgentLaunchFailedException("Agent 后置任务启动失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void beforeLaunch() {
|
||||
try {
|
||||
AgentConfigManager.setINSTANCE(agentConfigManagerClass.getDeclaredConstructor().newInstance());
|
||||
GlobalExceptionHandler.setExceptionCallback(agentExceptionCallbackClass.getDeclaredConstructor().newInstance());
|
||||
launchRunners(beforeLaunchRunners);
|
||||
} catch (Exception e) {
|
||||
throw new AgentLaunchFailedException("Agent 前置任务启动失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void launchRunners(List<Runnable> runners) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.isAssignableFromAnnotation;
|
||||
import static work.slhaf.partner.api.agent.util.AgentUtil.methodSignature;
|
||||
|
||||
/**
|
||||
@@ -66,6 +67,7 @@ public class CapabilityCheckFactory extends AgentBaseFactory {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
//TODO 对于CoordinateManager的所注类进行唯一性检验以及检测是否留有公开的无参构造方法
|
||||
loadCoresAndCapabilities();
|
||||
checkCountAndCapabilities();
|
||||
checkCapabilityMethods();
|
||||
@@ -83,8 +85,9 @@ public class CapabilityCheckFactory extends AgentBaseFactory {
|
||||
*/
|
||||
private void checkInjectCapability() {
|
||||
reflections.getFieldsAnnotatedWith(InjectCapability.class).forEach(field -> {
|
||||
if (!field.getDeclaringClass().isAssignableFrom(CapabilityHolder.class)) {
|
||||
throw new UnMatchedCapabilityException("InjectCapability 注解只能用于 CapabilityHolder 注解所在类");
|
||||
Class<?> declaringClass = field.getDeclaringClass();
|
||||
if (!isAssignableFromAnnotation(declaringClass, CapabilityHolder.class)){
|
||||
throw new UnMatchedCapabilityException("InjectCapability 注解只能用于 CapabilityHolder 注解所在类,检查该类是否使用了@CapabilityHolder注解或者受其标注的注解或父类: "+declaringClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package work.slhaf.partner.api.agent.factory.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.AgentBaseFactory;
|
||||
import work.slhaf.partner.api.agent.factory.config.exception.ConfigNotExistException;
|
||||
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.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.ConfigFactoryContext;
|
||||
@@ -10,7 +13,9 @@ import work.slhaf.partner.api.agent.runtime.config.FileAgentConfigManager;
|
||||
import work.slhaf.partner.api.chat.pojo.Message;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <h2>Agent启动流程 0</h2>
|
||||
@@ -20,6 +25,7 @@ import java.util.List;
|
||||
*
|
||||
* <p>下一步流程请参阅{@link ModuleCheckFactory}</p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
|
||||
private AgentConfigManager agentConfigManager;
|
||||
@@ -42,9 +48,31 @@ public class ConfigLoaderFactory extends AgentBaseFactory {
|
||||
@Override
|
||||
protected void run() {
|
||||
agentConfigManager.load();
|
||||
agentConfigManager.check();
|
||||
modelConfigMap.putAll(agentConfigManager.getModelConfigMap());
|
||||
modelPromptMap.putAll(agentConfigManager.getModelPromptMap());
|
||||
check();
|
||||
}
|
||||
|
||||
/**
|
||||
* 对模型Config与Prompt分别进行检验,除了都必须包含default外,还需要确保数量、key一致,毕竟是模型配置与提示词
|
||||
*/
|
||||
private void check() {
|
||||
log.info("[ConfigLoaderFactory]: 执行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("存在未被提示词包含的模型配置,该配置将无法生效!");
|
||||
}
|
||||
//检查提示词数量与`ActivateModel`的实现数量是否一致
|
||||
|
||||
log.info("[ConfigLoaderFactory]: 检测完毕.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package work.slhaf.partner.api.agent.factory.context;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -12,6 +13,6 @@ public class CapabilityFactoryContext {
|
||||
private final HashMap<String, Function<Object[], Object>> coordinatedMethodsRouterTable = new HashMap<>();
|
||||
private final HashMap<Class<?>, Object> capabilityCoreInstances = new HashMap<>();
|
||||
private final HashMap<Class<?>, Object> capabilityHolderInstances = new HashMap<>();
|
||||
private Set<Class<?>> cores;
|
||||
private Set<Class<?>> capabilities;
|
||||
private Set<Class<?>> cores = new HashSet<>();
|
||||
private Set<Class<?>> capabilities = new HashSet<>();
|
||||
}
|
||||
|
||||
@@ -56,18 +56,43 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
Set<Class<?>> moduleTypes = reflections.getTypesAnnotatedWith(AgentModule.class);
|
||||
Set<Class<?>> subModuleTypes = reflections.getTypesAnnotatedWith(AgentSubModule.class);
|
||||
AnnotatedModules annotatedModules = getAnnotatedModules();
|
||||
ExtendedModules extendedModules = getExtendedModules();
|
||||
checkIfClassCorresponds(annotatedModules, extendedModules);
|
||||
//检查注解AgentModule或AgentSubModule所在类是否继承了对应的抽象类
|
||||
annotationAbstractCheck(moduleTypes, AgentRunningModule.class);
|
||||
annotationAbstractCheck(subModuleTypes, AgentRunningSubModule.class);
|
||||
annotationAbstractCheck(annotatedModules.moduleTypes(), AgentRunningModule.class);
|
||||
annotationAbstractCheck(annotatedModules.subModuleTypes(), AgentRunningSubModule.class);
|
||||
//检查AgentModule是否具备无参构造方法
|
||||
moduleConstructorsCheck(moduleTypes);
|
||||
moduleConstructorsCheck(subModuleTypes);
|
||||
moduleConstructorsCheck(annotatedModules.moduleTypes());
|
||||
moduleConstructorsCheck(annotatedModules.subModuleTypes());
|
||||
//检查实现了ActivateModel的模块数量、名称与prompt是否一致
|
||||
activateModelImplCheck();
|
||||
}
|
||||
|
||||
private ExtendedModules getExtendedModules() {
|
||||
Set<Class<?>> moduleTypes = reflections.getSubTypesOf(AgentRunningModule.class)
|
||||
.stream()
|
||||
.filter(ClassUtil::isNormalClass)
|
||||
.collect(Collectors.toSet());
|
||||
Set<Class<?>> subModuleTypes = reflections.getSubTypesOf(AgentRunningSubModule.class)
|
||||
.stream()
|
||||
.filter(ClassUtil::isNormalClass)
|
||||
.collect(Collectors.toSet());
|
||||
return new ExtendedModules(moduleTypes, subModuleTypes);
|
||||
}
|
||||
|
||||
private AnnotatedModules getAnnotatedModules() {
|
||||
Set<Class<?>> moduleTypes = reflections.getTypesAnnotatedWith(AgentModule.class)
|
||||
.stream()
|
||||
.filter(ClassUtil::isNormalClass)
|
||||
.collect(Collectors.toSet());
|
||||
Set<Class<?>> subModuleTypes = reflections.getTypesAnnotatedWith(AgentSubModule.class)
|
||||
.stream()
|
||||
.filter(ClassUtil::isNormalClass)
|
||||
.collect(Collectors.toSet());
|
||||
return new AnnotatedModules(moduleTypes, subModuleTypes);
|
||||
}
|
||||
|
||||
private void moduleConstructorsCheck(Set<Class<?>> types) {
|
||||
for (Class<?> type : types) {
|
||||
try {
|
||||
@@ -164,4 +189,48 @@ public class ModuleCheckFactory extends AgentBaseFactory {
|
||||
throw new ModuleCheckException("存在未继承AgentInteractionModule.class的AgentModule实现: " + type.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfClassCorresponds(AnnotatedModules annotatedModules, ExtendedModules extendedModules) {
|
||||
// 检查是否有被@AgentModule注解但没有继承AgentRunningModule的类
|
||||
checkSets(annotatedModules.moduleTypes(), extendedModules.moduleTypes(),
|
||||
"存在被@AgentModule注解但未继承AgentRunningModule的类");
|
||||
|
||||
// 检查是否有继承AgentRunningModule但没有被@AgentModule注解的类
|
||||
checkSets(extendedModules.moduleTypes(), annotatedModules.moduleTypes(),
|
||||
"存在继承AgentRunningModule但未被@AgentModule注解的类");
|
||||
|
||||
// 检查是否有被@AgentSubModule注解但没有继承AgentRunningSubModule的类
|
||||
checkSets(annotatedModules.subModuleTypes(), extendedModules.subModuleTypes(),
|
||||
"存在被@AgentSubModule注解但未继承AgentRunningSubModule的类");
|
||||
|
||||
// 检查是否有继承AgentRunningSubModule但没有被@AgentSubModule注解的类
|
||||
checkSets(extendedModules.subModuleTypes(), annotatedModules.subModuleTypes(),
|
||||
"存在继承AgentRunningSubModule但未被@AgentSubModule注解的类");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查源集合中是否有不在目标集合中的元素
|
||||
* @param source 源集合
|
||||
* @param target 目标集合
|
||||
* @param errorMessage 错误信息前缀
|
||||
*/
|
||||
private void checkSets(Set<Class<?>> source, Set<Class<?>> target, String errorMessage) {
|
||||
// 只有在需要时才创建HashSet以节省内存
|
||||
if (!target.containsAll(source)) {
|
||||
// 使用流式处理找出差异部分,避免创建完整的中间集合
|
||||
String classNames = source.stream()
|
||||
.filter(clazz -> !target.contains(clazz))
|
||||
.map(Class::getSimpleName)
|
||||
.limit(10) // 限制显示数量,避免信息泄露
|
||||
.collect(Collectors.joining(", ", "[", "]"));
|
||||
|
||||
throw new ModuleCheckException(errorMessage + ": " + classNames);
|
||||
}
|
||||
}
|
||||
|
||||
private record AnnotatedModules(Set<Class<?>> moduleTypes, Set<Class<?>> subModuleTypes) {
|
||||
}
|
||||
|
||||
private record ExtendedModules(Set<Class<?>> moduleTypes, Set<Class<?>> subModuleTypes) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,7 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
}
|
||||
|
||||
private void updateCapabilityHolderInstances() {
|
||||
//TODO 扫描并添加所有与@CapabilityHolder相关的实例
|
||||
capabilityHolderInstances.putAll(moduleInstances);
|
||||
capabilityHolderInstances.putAll(subModuleInstances);
|
||||
}
|
||||
@@ -203,7 +204,7 @@ public class ModuleProxyFactory extends AgentBaseFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private record ModuleProxyInterceptor(List<MetaMethod> postHookMethods, List<MetaMethod> preHookMethods) {
|
||||
public record ModuleProxyInterceptor(List<MetaMethod> postHookMethods, List<MetaMethod> preHookMethods) {
|
||||
@RuntimeType
|
||||
public Object intercept(@Origin Method method, @AllArguments Object[] allArguments, @SuperCall Callable<?> zuper, @This Object proxy) throws Exception {
|
||||
for (MetaMethod metaMethod : preHookMethods) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import work.slhaf.partner.api.agent.factory.context.AgentRegisterContext;
|
||||
import work.slhaf.partner.api.agent.factory.context.ModuleFactoryContext;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.CoreModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.pojo.MetaSubModule;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
|
||||
@@ -80,14 +81,24 @@ public class ModuleRegisterFactory extends AgentBaseFactory {
|
||||
continue;
|
||||
}
|
||||
Class<? extends AgentRunningModule> clazz = module.asSubclass(AgentRunningModule.class);
|
||||
AgentModule agentModule = clazz.getAnnotation(AgentModule.class);
|
||||
MetaModule metaModule = new MetaModule();
|
||||
metaModule.setName(agentModule.name());
|
||||
metaModule.setOrder(agentModule.order());
|
||||
metaModule.setClazz(clazz);
|
||||
MetaModule metaModule = getMetaModule(clazz);
|
||||
moduleList.add(metaModule);
|
||||
}
|
||||
moduleList.sort(Comparator.comparing(MetaModule::getOrder));
|
||||
}
|
||||
|
||||
private static MetaModule getMetaModule(Class<? extends AgentRunningModule> clazz) {
|
||||
MetaModule metaModule = new MetaModule();
|
||||
AgentModule agentModule;
|
||||
if (clazz.isAnnotationPresent(CoreModule.class)){
|
||||
agentModule = CoreModule.class.getAnnotation(AgentModule.class);
|
||||
}else{
|
||||
agentModule = clazz.getAnnotation(AgentModule.class);
|
||||
}
|
||||
metaModule.setName(agentModule.name());
|
||||
metaModule.setOrder(agentModule.order());
|
||||
metaModule.setClazz(clazz);
|
||||
return metaModule;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package work.slhaf.partner.api.agent.factory.module.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@AgentModule(name = "core",order = 5)
|
||||
public @interface CoreModule {
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Set;
|
||||
public abstract class AgentConfigManager {
|
||||
|
||||
@Setter
|
||||
public static AgentConfigManager INSTANCE;
|
||||
public static AgentConfigManager INSTANCE = new FileAgentConfigManager();
|
||||
private static final String DEFAULT_KEY = "default";
|
||||
|
||||
protected HashMap<String, ModelConfig> modelConfigMap;
|
||||
@@ -62,27 +62,6 @@ public abstract class AgentConfigManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对模型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);
|
||||
|
||||
@@ -88,9 +88,7 @@ public interface ActivateModel {
|
||||
((Module) this).setModel(model);
|
||||
}
|
||||
|
||||
default String modelKey(){
|
||||
return this.getClass().getAnnotation(AgentModule.class).name();
|
||||
}
|
||||
String modelKey();
|
||||
|
||||
boolean withBasicPrompt();
|
||||
|
||||
|
||||
@@ -10,6 +10,28 @@ import java.util.stream.Collectors;
|
||||
|
||||
public final class AgentUtil {
|
||||
|
||||
public static boolean isAssignableFromAnnotation(Class<?> clazz,Class<? extends Annotation> targetAnnotation){
|
||||
Set<Class<?>> visited = new HashSet<>();
|
||||
return isAssignableFromAnnotation(clazz,targetAnnotation,visited);
|
||||
}
|
||||
|
||||
private static boolean isAssignableFromAnnotation(Class<?> clazz,Class<? extends Annotation> targetAnnotation,Set<Class<?>> visited){
|
||||
if (!visited.add(clazz)){
|
||||
return false;
|
||||
}
|
||||
if (clazz.isAnnotationPresent(targetAnnotation)){
|
||||
return true;
|
||||
}
|
||||
Annotation[] annotations = clazz.getAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
boolean ok = isAssignableFromAnnotation(annotation.annotationType(),targetAnnotation,visited);
|
||||
if (ok){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String methodSignature(Method method) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
|
||||
@@ -8,9 +8,9 @@ import work.slhaf.partner.runtime.interaction.WebSocketGateway;
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Agent.newAgent(Main.class)
|
||||
.setGateway(WebSocketGateway.initialize())
|
||||
.setAgentConfigManager(new PartnerAgentConfigManager())
|
||||
.setAgentExceptionCallback(new PartnerExceptionCallback())
|
||||
.setAgentConfigManager(PartnerAgentConfigManager.class)
|
||||
.setGateway(WebSocketGateway.class)
|
||||
.setAgentExceptionCallback(PartnerExceptionCallback.class)
|
||||
.launch();
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,6 @@ public class CoordinatedManager implements Serializable {
|
||||
private PerceiveCore perceiveCore;
|
||||
private DispatchCore dispatchCore;
|
||||
|
||||
private CoordinatedManager() {
|
||||
}
|
||||
|
||||
|
||||
public static CoordinatedManager getInstance() throws IOException, ClassNotFoundException {
|
||||
if (coordinatedManager == null) {
|
||||
synchronized (CoordinatedManager.class) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@@ -185,5 +186,10 @@ public class CognationCore extends PersistableObject {
|
||||
public List<EvaluatedSlice> getActivatedSlices(String userId) {
|
||||
return activeData.getActivatedSlices().get(userId);
|
||||
}
|
||||
|
||||
@CapabilityMethod
|
||||
public Lock getMessageLock() {
|
||||
return messageLock;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@ public class CoreModel extends CoreRunningModule implements ActivateModel {
|
||||
chatClient().setTop_p(0.7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String modelKey() {
|
||||
return "core_model";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withBasicPrompt() {
|
||||
return true;
|
||||
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
|
||||
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel;
|
||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
|
||||
@@ -31,6 +32,7 @@ import static work.slhaf.partner.common.util.ExtractUtil.fixTopicPath;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Slf4j
|
||||
@AgentSubModule
|
||||
public class MemorySelectExtractor extends AgentRunningSubModule<PartnerRunningFlowContext, ExtractorResult>
|
||||
implements ActivateModel {
|
||||
|
||||
|
||||
@@ -25,10 +25,6 @@ import static work.slhaf.partner.common.util.ExtractUtil.fixTopicPath;
|
||||
@AgentSubModule
|
||||
public class MultiSummarizer extends AgentRunningSubModule<SummarizeInput, SummarizeResult> implements ActivateModel {
|
||||
|
||||
private MultiSummarizer() {
|
||||
modelSettings();
|
||||
}
|
||||
|
||||
@Init
|
||||
public void init() {
|
||||
updateChatClientSettings();
|
||||
|
||||
@@ -32,9 +32,8 @@ public class WebSocketGateway extends WebSocketServer implements AgentGateway<Pa
|
||||
// 记录最后一次收到Pong的时间
|
||||
private final ConcurrentHashMap<WebSocket, Long> lastPongTimes = new ConcurrentHashMap<>();
|
||||
|
||||
public static WebSocketGateway initialize() {
|
||||
PartnerAgentConfigManager configManager = (PartnerAgentConfigManager) AgentConfigManager.INSTANCE;
|
||||
return new WebSocketGateway(configManager.getConfig().getPort());
|
||||
public WebSocketGateway() {
|
||||
this(((PartnerAgentConfigManager) AgentConfigManager.INSTANCE).getConfig().getPort());
|
||||
}
|
||||
|
||||
private WebSocketGateway(int port) {
|
||||
|
||||
18
doc/如何启动.md
Normal file
18
doc/如何启动.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Partner 项目启动流程
|
||||
|
||||
> 由于整个项目启动依赖提前写好的配置文件,所以在启动项目之前,最好阅读先该文档,准备好必要的配置,避免启动失败
|
||||
|
||||
## 前置操作
|
||||
|
||||
确保已经安装`Java21`环境
|
||||
|
||||
克隆项目至本地:
|
||||
```bash
|
||||
git clone https://github.com/slhafzjw/Partner.git
|
||||
```
|
||||
|
||||
## 准备配置
|
||||
克隆好项目之后,在项目的根目录创建目录`config/`
|
||||
### 准备基础配置文件
|
||||
|
||||
|
||||
Reference in New Issue
Block a user