开始推进行动模块(ActionModule); 针对框架与本体分别进行了一系列架构优化。

框架:
- 调整模块注册以及AgentRunningFlow的相关逻辑,以支持同组模块并发执行,将以@AgentModule注解中的order属性区分组间顺序先后及是否同组
- 针对@CoordinateManager注解新增了Core的自动注入处理,以便更好的协调不同Core的逻辑

本体: - 开始推进行动模块。将采取类似记忆模块的分层思路,分为ActionPlanner与ActionDispatcher两个主要模块,再各自细分子模块划分
- 将CognationCore从核心统筹的身份下降至与其他核心平级,同时将其中的序列化逻辑抽取至统一的PartnerCore父类,所有核心都将继承该类以获得序列化能力,不同core的内容将序列化至各自的memory文件
- 将SessionManager移除,相关逻辑迁移至CognationCore,统一序列化逻辑的同时又保证语义正确
- 将CognationCore中的某些缓存性质逻辑移动至CacheCore,确保语义正确
- 调整了目录结构以适应优化过的架构
This commit is contained in:
2025-10-12 16:23:11 +08:00
parent 41bf19f43e
commit a10a149edb
94 changed files with 1021 additions and 793 deletions

6
.idea/kotlinc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="2.2.0" />
</component>
</project>

1
.idea/vcs.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$USER_HOME$/Projects/IdeaProjects/Projects/Partner" vcs="Git" />
</component> </component>
</project> </project>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>Partner</artifactId>
<groupId>work.slhaf</groupId>
<version>0.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Partner-Api</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<properties>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -13,6 +13,7 @@ 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.AgentSubModule;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
@@ -99,7 +100,7 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
} }
Object o = constructor.newInstance(); Object o = constructor.newInstance();
capabilityHolderInstances.put(clazz, o); capabilityHolderInstances.put(clazz, o);
}catch (Exception e){ } catch (Exception e) {
throw new CapabilityFactoryExecuteFailedException("创建代理对象失败: " + clazz, e); throw new CapabilityFactoryExecuteFailedException("创建代理对象失败: " + clazz, e);
} }
} }
@@ -149,7 +150,7 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
for (Class<?> c : reflections.getTypesAnnotatedWith(CoordinateManager.class)) { for (Class<?> c : reflections.getTypesAnnotatedWith(CoordinateManager.class)) {
Constructor<?> constructor = c.getDeclaredConstructor(); Constructor<?> constructor = c.getDeclaredConstructor();
Object instance = constructor.newInstance(); Object instance = constructor.newInstance();
setCores(instance, c);
Arrays.stream(c.getMethods()) Arrays.stream(c.getMethods())
.filter(method -> method.isAnnotationPresent(Coordinated.class)) .filter(method -> method.isAnnotationPresent(Coordinated.class))
.forEach(method -> { .forEach(method -> {
@@ -160,6 +161,15 @@ public class CapabilityRegisterFactory extends AgentBaseFactory {
return map; return map;
} }
private void setCores(Object cmInstance, Class<?> cmClazz) throws IllegalAccessException {
for (Field field : cmClazz.getFields()) {
if (field.getType().isAnnotationPresent(CapabilityCore.class)) {
field.setAccessible(true);
field.set(cmInstance, coreInstances.get(field.getType()));
}
}
}
/** /**
* 扫描`@Capability`与`@CapabilityMethod`注解的类与方法 * 扫描`@Capability`与`@CapabilityMethod`注解的类与方法
* 将`capabilityValue.methodSignature`作为key,函数对象为通过反射拿到的core实例对应的方法 * 将`capabilityValue.methodSignature`作为key,函数对象为通过反射拿到的core实例对应的方法

View File

@@ -5,6 +5,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/**
* Core的协调类该注解的实现类中如果存在任何{@link CapabilityCore}实例的引用,都将被自动注入
*/
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface CoordinateManager { public @interface CoordinateManager {

View File

@@ -9,8 +9,7 @@ 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.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import java.util.HashMap; import java.util.*;
import java.util.List;
@Slf4j @Slf4j
@Data @Data
@@ -23,7 +22,8 @@ public abstract class AgentConfigManager {
protected HashMap<String, ModelConfig> modelConfigMap; protected HashMap<String, ModelConfig> modelConfigMap;
protected HashMap<String, List<Message>> modelPromptMap; protected HashMap<String, List<Message>> modelPromptMap;
protected HashMap<String, Boolean> moduleEnabledStatus; protected HashMap<String, Boolean> moduleEnabledStatus;
protected List<MetaModule> moduleList; protected Map<Integer, List<MetaModule>> moduleOrderedMap = new LinkedHashMap<>();
protected Map<String, MetaModule> moduleMap = new HashMap<>();
public void load() { public void load() {
modelConfigMap = loadModelConfig(); modelConfigMap = loadModelConfig();
@@ -38,11 +38,24 @@ public abstract class AgentConfigManager {
protected abstract void dumpModuleEnabledStatus(); protected abstract void dumpModuleEnabledStatus();
protected abstract HashMap<String, Boolean> loadModuleEnabledStatusMap(); protected abstract HashMap<String, Boolean> loadModuleEnabledStatusMap(List<MetaModule> moduleList);
public void moduleEnabledStatusFilterAndRecord(List<MetaModule> moduleList) { public void moduleEnabledStatusFilterAndRecord(List<MetaModule> moduleList) {
this.moduleList = moduleList; updateModuleMap(moduleList);
this.moduleEnabledStatus = loadModuleEnabledStatusMap(); updateModuleEnabledStatus(moduleList);
}
private void updateModuleMap(List<MetaModule> moduleList) {
//在ModuleRegisterFactory已进行过排序操作
for (MetaModule module : moduleList) {
int k = module.getOrder();
moduleOrderedMap.computeIfAbsent(k, order -> new ArrayList<>()).add(module);
moduleMap.put(module.getName(), module);
}
}
private void updateModuleEnabledStatus(List<MetaModule> moduleList) {
this.moduleEnabledStatus = loadModuleEnabledStatusMap(moduleList);
boolean unmatch = false; boolean unmatch = false;
for (MetaModule metaModule : moduleList) { for (MetaModule metaModule : moduleList) {
@@ -84,12 +97,7 @@ public abstract class AgentConfigManager {
} }
moduleEnabledStatus.put(key, status); moduleEnabledStatus.put(key, status);
dumpModuleEnabledStatus(); dumpModuleEnabledStatus();
for (MetaModule metaModule : moduleList) { moduleMap.get(key).setEnabled(status);
if (metaModule.getName().equals(key)) {
metaModule.setEnabled(status);
break;
}
}
} }
} }

View File

@@ -74,7 +74,7 @@ public class FileAgentConfigManager extends AgentConfigManager {
} }
@Override @Override
protected HashMap<String, Boolean> loadModuleEnabledStatusMap() { protected HashMap<String, Boolean> loadModuleEnabledStatusMap(List<MetaModule> moduleList) {
File file = new File(MODULE_ENABLED_STATUS_CONFIG_FILE); File file = new File(MODULE_ENABLED_STATUS_CONFIG_FILE);
try { try {
moduleEnabledStatus = new HashMap<>(); moduleEnabledStatus = new HashMap<>();

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.api.agent.runtime.exception;
public class AgentRunningFailedException extends AgentRuntimeException{
public AgentRunningFailedException(String message) {
super(message);
}
public AgentRunningFailedException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -9,18 +9,28 @@ public class GlobalExceptionHandler {
private AgentExceptionCallback exceptionCallback = new LogAgentExceptionCallback(); private AgentExceptionCallback exceptionCallback = new LogAgentExceptionCallback();
public void handle(Throwable e) { public boolean handle(Throwable e) {
boolean exit;
switch (e.getClass().getSimpleName()) { Throwable cause = e.getCause();
case "AgentRuntimeException": switch (cause) {
exceptionCallback.onRuntimeException((AgentRuntimeException) e); case AgentRunningFailedException arfe -> {
break; exit = true;
case "AgentLaunchFailedException": exceptionCallback.onRuntimeException((AgentRuntimeException) cause);
exceptionCallback.onFailedException((AgentLaunchFailedException) e); }
break; case AgentRuntimeException are -> {
default: exit = false;
log.error("未知异常: ", e); exceptionCallback.onRuntimeException((AgentRuntimeException) cause);
}
case AgentLaunchFailedException alfe -> {
exit = true;
exceptionCallback.onFailedException((AgentLaunchFailedException) cause);
}
default -> {
exit = true;
log.error("意外异常: ", cause);
}
} }
return exit;
} }
public static void setExceptionCallback(AgentExceptionCallback callback) { public static void setExceptionCallback(AgentExceptionCallback callback) {

View File

@@ -8,14 +8,15 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.AgentRunningFlow;
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext; import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext;
import java.util.List; import java.util.List;
import java.util.Map;
public abstract class AgentInteractionAdapter<I extends AgentInputData, O extends AgentOutputData, C extends RunningFlowContext> { public abstract class AgentInteractionAdapter<I extends AgentInputData, O extends AgentOutputData, C extends RunningFlowContext> {
protected AgentRunningFlow<C> agentRunningFlow = new AgentRunningFlow<>(); protected AgentRunningFlow<C> agentRunningFlow = new AgentRunningFlow<>();
protected List<MetaModule> moduleList = AgentConfigManager.INSTANCE.getModuleList(); protected Map<Integer, List<MetaModule>> moduleOrderedMap = AgentConfigManager.INSTANCE.getModuleOrderedMap();
public C call(C finalInputData){ public C call(C finalInputData){
return agentRunningFlow.launch(moduleList, finalInputData); return agentRunningFlow.launch(moduleOrderedMap, finalInputData);
} }
protected abstract O parseOutputData(C outputContext); protected abstract O parseOutputData(C outputContext);

View File

@@ -1,27 +1,52 @@
package work.slhaf.partner.api.agent.runtime.interaction.flow; package work.slhaf.partner.api.agent.runtime.interaction.flow;
import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule; import work.slhaf.partner.api.agent.factory.module.pojo.MetaModule;
import work.slhaf.partner.api.agent.runtime.exception.AgentRuntimeException;
import work.slhaf.partner.api.agent.runtime.exception.GlobalExceptionHandler; import work.slhaf.partner.api.agent.runtime.exception.GlobalExceptionHandler;
import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext; import work.slhaf.partner.api.agent.runtime.interaction.flow.entity.RunningFlowContext;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/** /**
* Agent执行流程 * Agent执行流程
*/ */
public class AgentRunningFlow<C extends RunningFlowContext> { public class AgentRunningFlow<C extends RunningFlowContext> {
public C launch(List<MetaModule> moduleList, C interactionContext){ public C launch(Map<Integer, List<MetaModule>> modules, C interactionContext) {
try { try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
//流程执行启动 //流程执行启动
for (MetaModule metaModule : moduleList) { for (Map.Entry<Integer, List<MetaModule>> entry : modules.entrySet()) {
metaModule.getInstance().execute(interactionContext); List<Future<?>> futures = new ArrayList<>();
List<MetaModule> moduleList = entry.getValue();
for (MetaModule module : moduleList) {
Future<?> future = executor.submit(() -> {
try {
module.getInstance().execute(interactionContext);
} catch (Exception e) {
throw new AgentRuntimeException("模块执行出错: " + module.getName(), e);
}
});
futures.add(future);
}
for (Future<?> future : futures) {
try {
future.get();
} catch (Exception e) {
boolean exit = GlobalExceptionHandler.INSTANCE.handle(e);
if (exit) throw new AgentRuntimeException("Agent执行出错!", e);
interactionContext.getErrMsg().add(e.getLocalizedMessage());
}
}
} }
interactionContext.setOk(1); interactionContext.setOk(1);
}catch (Exception e){ } catch (Exception e) {
GlobalExceptionHandler.INSTANCE.handle(e);
interactionContext.setOk(0); interactionContext.setOk(0);
interactionContext.setErrMsg(e.getMessage()); interactionContext.getErrMsg().add(e.getLocalizedMessage());
} }
return interactionContext; return interactionContext;
} }

View File

@@ -87,6 +87,9 @@ public interface ActivateModel {
((Module) this).setModel(model); ((Module) this).setModel(model);
} }
/**
* 对应调用的模型配置名称
*/
String modelKey(); String modelKey();
boolean withBasicPrompt(); boolean withBasicPrompt();

View File

@@ -4,6 +4,9 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.api.common.entity.PersistableObject;
import java.util.ArrayList;
import java.util.List;
/** /**
* 流程上下文 * 流程上下文
*/ */
@@ -11,5 +14,5 @@ import work.slhaf.partner.api.common.entity.PersistableObject;
@Data @Data
public abstract class RunningFlowContext extends PersistableObject { public abstract class RunningFlowContext extends PersistableObject {
protected int ok; protected int ok;
protected String errMsg; protected List<String> errMsg = new ArrayList<>();
} }

View File

@@ -6,11 +6,12 @@ import net.bytebuddy.matcher.ElementMatchers;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningModule;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
public class ModuleProxyTest { public class ModuleProxyTest {
@Test @Test
public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {
Class<? extends AgentRunningModule> clazz = new ByteBuddy().subclass(MyAgentRunningModule.class) Class<? extends AgentRunningModule> clazz = new ByteBuddy().subclass(MyAgentRunningModule.class)
.method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class)) .method(ElementMatchers.isOverriddenFrom(AgentRunningModule.class))
.intercept(MethodDelegation.to( .intercept(MethodDelegation.to(

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>Partner</artifactId>
<groupId>work.slhaf</groupId>
<version>0.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Partner-Main</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer>
<mainClass>work.slhaf.partner.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -22,6 +22,12 @@
<artifactId>Partner-Api</artifactId> <artifactId>Partner-Api</artifactId>
<version>0.5.0</version> <version>0.5.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.10.2</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
@@ -30,4 +36,35 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>work.slhaf.partner.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View File

@@ -1,4 +1,4 @@
package work.slhaf; package work.slhaf.partner;
import work.slhaf.partner.api.agent.Agent; import work.slhaf.partner.api.agent.Agent;
import work.slhaf.partner.common.config.PartnerAgentConfigManager; import work.slhaf.partner.common.config.PartnerAgentConfigManager;

View File

@@ -1,43 +0,0 @@
package work.slhaf.partner.common.exception.callback;
import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.runtime.exception.pojo.GlobalException;
import work.slhaf.partner.runtime.exception.pojo.GlobalExceptionData;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Slf4j
public class GlobalExceptionHandler {
private static final String EXCEPTION_STATIC_PATH = "./data/exception_snapshot/";
public static void writeExceptionState(GlobalException exception) {
GlobalExceptionData exceptionData = exception.getData();
Path filePath = Paths.get(EXCEPTION_STATIC_PATH, exceptionData.getExceptionTime() + ".dat");
try {
Files.createDirectories(Path.of(EXCEPTION_STATIC_PATH));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()));
oos.writeObject(exceptionData);
oos.close();
log.warn("[GlobalExceptionHandler] 捕获异常, 已保存到: {}", filePath);
} catch (IOException e) {
log.error("[GlobalExceptionHandler] 捕获异常, 保存失败: ", e);
}
}
public static GlobalExceptionData readExceptionState(String filePath) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
GlobalExceptionData exceptionData = (GlobalExceptionData) ois.readObject();
ois.close();
log.info("[GlobalExceptionHandler] 已从: {} 读取异常快照", filePath);
return exceptionData;
} catch (IOException | ClassNotFoundException e) {
log.error("[GlobalExceptionHandler] 读取异常, 读取失败: ", e);
return null;
}
}
}

View File

@@ -5,16 +5,13 @@ import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.factory.capability.annotation.CoordinateManager; import work.slhaf.partner.api.agent.factory.capability.annotation.CoordinateManager;
import work.slhaf.partner.api.agent.factory.capability.annotation.Coordinated; import work.slhaf.partner.api.agent.factory.capability.annotation.Coordinated;
import work.slhaf.partner.api.chat.constant.ChatConstant; import work.slhaf.partner.api.chat.constant.ChatConstant;
import work.slhaf.partner.common.exception.callback.GlobalExceptionHandler; import work.slhaf.partner.core.cache.CacheCore;
import work.slhaf.partner.core.cognation.CognationCore; import work.slhaf.partner.core.cognation.CognationCore;
import work.slhaf.partner.core.submodule.cache.CacheCore; import work.slhaf.partner.core.memory.MemoryCore;
import work.slhaf.partner.core.submodule.dispatch.DispatchCore; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import work.slhaf.partner.core.submodule.memory.MemoryCore; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemorySliceResult;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.perceive.PerceiveCore;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySliceResult;
import work.slhaf.partner.core.submodule.perceive.PerceiveCore;
import work.slhaf.partner.runtime.exception.pojo.GlobalException;
import java.io.IOException; import java.io.IOException;
import java.io.Serial; import java.io.Serial;
@@ -35,35 +32,13 @@ public class CoordinatedManager implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static volatile CoordinatedManager coordinatedManager;
private final Lock sliceInsertLock = new ReentrantLock(); private final Lock sliceInsertLock = new ReentrantLock();
//在框架将自动注入core,详见CapabilityRegistryFactory
private CognationCore cognationCore; private CognationCore cognationCore;
private CacheCore cacheCore; private CacheCore cacheCore;
private MemoryCore memoryCore; private MemoryCore memoryCore;
private PerceiveCore perceiveCore; private PerceiveCore perceiveCore;
private DispatchCore dispatchCore;
public static CoordinatedManager getInstance() throws IOException, ClassNotFoundException {
if (coordinatedManager == null) {
synchronized (CoordinatedManager.class) {
if (coordinatedManager == null) {
coordinatedManager = new CoordinatedManager();
coordinatedManager.setCognationCore(CognationCore.getInstance());
coordinatedManager.setCores();
log.info("[CoordinatedManager] MemoryManager注册完毕...");
}
}
}
return coordinatedManager;
}
private void setCores() {
this.setCacheCore(this.getCognationCore().getCacheCore());
this.setMemoryCore(this.getCognationCore().getMemoryCore());
this.setPerceiveCore(this.getCognationCore().getPerceiveCore());
}
@Coordinated(capability = "memory") @Coordinated(capability = "memory")
public MemoryResult selectMemory(String topicPathStr) { public MemoryResult selectMemory(String topicPathStr) {
@@ -89,7 +64,6 @@ public class CoordinatedManager implements Serializable {
memoryResult = new MemoryResult(); memoryResult = new MemoryResult();
memoryResult.setRelatedMemorySliceResult(new ArrayList<>()); memoryResult.setRelatedMemorySliceResult(new ArrayList<>());
memoryResult.setMemorySliceResult(new CopyOnWriteArrayList<>()); memoryResult.setMemorySliceResult(new CopyOnWriteArrayList<>());
GlobalExceptionHandler.writeExceptionState(new GlobalException(e.getLocalizedMessage()));
} }
return cacheFilter(memoryResult); return cacheFilter(memoryResult);
} }
@@ -127,7 +101,6 @@ public class CoordinatedManager implements Serializable {
} }
} catch (Exception e) { } catch (Exception e) {
log.error("[CoordinatedManager] 插入记忆时出错: ", e); log.error("[CoordinatedManager] 插入记忆时出错: ", e);
GlobalExceptionHandler.writeExceptionState(new GlobalException("插入记忆时出错: " + e.getLocalizedMessage()));
} }
log.debug("[CoordinatedManager] 插入切片: {}, 路径: {}", memorySlice, topicPath); log.debug("[CoordinatedManager] 插入切片: {}, 路径: {}", memorySlice, topicPath);
sliceInsertLock.unlock(); sliceInsertLock.unlock();

View File

@@ -0,0 +1,93 @@
package work.slhaf.partner.core;
import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
import work.slhaf.partner.api.common.entity.PersistableObject;
import work.slhaf.partner.common.config.PartnerAgentConfigManager;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
@Slf4j
public abstract class PartnerCore<T extends PartnerCore<T>> extends PersistableObject {
private static final String STORAGE_DIR = "./data/memory/";
private final String id = ((PartnerAgentConfigManager) AgentConfigManager.INSTANCE).getConfig().getAgentId();
public PartnerCore() throws IOException, ClassNotFoundException {
createStorageDirectory();
Path filePath = getFilePath(id);
if (Files.exists(filePath)) {
T deserialize = deserialize();
setupData(deserialize, (T) this);
} else {
FileUtils.createParentDirectories(filePath.toFile().getParentFile());
this.serialize();
}
setupHook(this);
log.info("[{}] 注册完毕", getCoreKey());
}
private void setupHook(PartnerCore<T> temp) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
temp.serialize();
log.info("[{}] 已保存", getCoreKey());
} catch (IOException e) {
log.error("[{}] 保存失败: ", getCoreKey(), e);
}
}));
}
private void setupData(T source, T current) {
BeanUtil.copyProperties(source, current);
}
public void serialize() throws IOException {
//先写入到临时文件,如果正常写入则覆盖原文件
Path filePath = getFilePath(id + "-temp");
Files.createDirectories(Path.of(STORAGE_DIR));
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()));
oos.writeObject(this);
oos.close();
Path path = getFilePath(id);
Files.move(filePath, path, StandardCopyOption.REPLACE_EXISTING);
log.info("[{}] 已保存到: {}", getCoreKey(), path);
} catch (IOException e) {
Files.delete(filePath);
log.error("[{}] 序列化保存失败: {}", getCoreKey(), e.getMessage());
}
}
private T deserialize() throws IOException, ClassNotFoundException {
Path filePath = getFilePath(id);
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(filePath.toFile()))) {
T graph = (T) ois.readObject();
log.info("[{}] 已从文件加载: {}", getCoreKey(), filePath);
return graph;
}
}
private Path getFilePath(String s) {
return Paths.get(STORAGE_DIR, s + "-" + getCoreKey() + ".memory");
}
private void createStorageDirectory() {
try {
Files.createDirectories(Paths.get(STORAGE_DIR));
} catch (IOException e) {
log.error("[{}]创建存储目录失败: {}", getCoreKey(), e.getMessage());
}
}
protected abstract String getCoreKey();
}

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.core.action.entity;
import lombok.Data;
@Data
public class ActionData {
private String key;
private String[] array;
private String reason;
private String description;
}

View File

@@ -0,0 +1,5 @@
package work.slhaf.partner.core.action.entity;
public enum ActionStatus {
SUCCESS, FAILED, EXECUTING, WAITING
}

View File

@@ -0,0 +1,5 @@
package work.slhaf.partner.core.action.entity;
public enum ActionType {
IMMEDIATE, PLANNING
}

View File

@@ -0,0 +1,13 @@
package work.slhaf.partner.core.action.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class MetaActionInfo {
private ActionData actionData;
private ActionStatus status;
private String Result;
private LocalDateTime dateTime;
}

View File

@@ -1,9 +1,11 @@
package work.slhaf.partner.core.submodule.cache; package work.slhaf.partner.core.cache;
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@Capability(value = "cache") @Capability(value = "cache")
@@ -13,4 +15,11 @@ public interface CacheCapability {
void updateDialogMap(LocalDateTime dateTime, String newDialogCache); void updateDialogMap(LocalDateTime dateTime, String newDialogCache);
String getDialogMapStr(); String getDialogMapStr();
String getUserDialogMapStr(String userId); String getUserDialogMapStr(String userId);
void updateActivatedSlices(String userId, List<EvaluatedSlice> memorySlices);
String getActivatedSlicesStr(String userId);
HashMap<String, List<EvaluatedSlice>> getActivatedSlices();
void clearActivatedSlices(String userId);
boolean hasActivatedSlices(String userId);
int getActivatedSlicesSize(String userId);
List<EvaluatedSlice> getActivatedSlices(String userId);
} }

View File

@@ -1,14 +1,18 @@
package work.slhaf.partner.core.submodule.cache; package work.slhaf.partner.core.cache;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.core.PartnerCore;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.cognation.pojo.ActiveData;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.core.memory.pojo.MemoryResult;
import work.slhaf.partner.core.memory.pojo.MemorySlice;
import java.io.IOException;
import java.io.Serial; import java.io.Serial;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -19,11 +23,11 @@ import java.util.concurrent.ConcurrentHashMap;
@Slf4j @Slf4j
@CapabilityCore(value = "cache") @CapabilityCore(value = "cache")
@Getter @Getter
public class CacheCore extends PersistableObject { @Setter
public class CacheCore extends PartnerCore<CacheCore> {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static volatile CacheCore cacheCore;
/** /**
* 近两日的对话总结缓存, 用于为大模型提供必要的记忆补充, hashmap以切片的存储时间为键总结为值 * 近两日的对话总结缓存, 用于为大模型提供必要的记忆补充, hashmap以切片的存储时间为键总结为值
@@ -58,13 +62,11 @@ public class CacheCore extends PersistableObject {
*/ */
private Set<Long> selectedSlices = new HashSet<>(); private Set<Long> selectedSlices = new HashSet<>();
public CacheCore() { private ActiveData activeData = new ActiveData();
cacheCore = this;
public CacheCore() throws IOException, ClassNotFoundException {
} }
public static CacheCore getInstance(){
return cacheCore;
}
@CapabilityMethod @CapabilityMethod
public void updateDialogMap(LocalDateTime dateTime, String newDialogCache) { public void updateDialogMap(LocalDateTime dateTime, String newDialogCache) {
@@ -179,4 +181,44 @@ public class CacheCore extends PersistableObject {
return null; return null;
} }
@CapabilityMethod
public void updateActivatedSlices(String userId, List<EvaluatedSlice> memorySlices) {
activeData.updateActivatedSlices(userId, memorySlices);
log.debug("[CoordinatedManager] 已更新激活切片, userId: {}", userId);
}
@CapabilityMethod
public String getActivatedSlicesStr(String userId) {
return activeData.getActivatedSlicesStr(userId);
}
@CapabilityMethod
public HashMap<String, List<EvaluatedSlice>> getActivatedSlices() {
return activeData.getActivatedSlices();
}
@CapabilityMethod
public void clearActivatedSlices(String userId) {
activeData.clearActivatedSlices(userId);
}
@CapabilityMethod
public boolean hasActivatedSlices(String userId) {
return activeData.hasActivatedSlices(userId);
}
@CapabilityMethod
public int getActivatedSlicesSize(String userId) {
return activeData.getActivatedSlices().get(userId).size();
}
@CapabilityMethod
public List<EvaluatedSlice> getActivatedSlices(String userId) {
return activeData.getActivatedSlices().get(userId);
}
@Override
protected String getCoreKey() {
return "cache-core";
}
} }

View File

@@ -3,7 +3,7 @@ package work.slhaf.partner.core.cognation;
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
import work.slhaf.partner.api.agent.factory.capability.annotation.ToCoordinated; import work.slhaf.partner.api.agent.factory.capability.annotation.ToCoordinated;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice; import work.slhaf.partner.api.chat.pojo.MetaMessage;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -15,14 +15,14 @@ public interface CognationCapability {
List<Message> getChatMessages(); List<Message> getChatMessages();
void setChatMessages(List<Message> chatMessages); void setChatMessages(List<Message> chatMessages);
void cleanMessage(List<Message> messages); void cleanMessage(List<Message> messages);
void updateActivatedSlices(String userId, List<EvaluatedSlice> memorySlices);
String getActivatedSlicesStr(String userId);
HashMap<String, List<EvaluatedSlice>> getActivatedSlices();
void clearActivatedSlices(String userId);
boolean hasActivatedSlices(String userId);
int getActivatedSlicesSize(String userId);
List<EvaluatedSlice> getActivatedSlices(String userId);
Lock getMessageLock(); Lock getMessageLock();
void addMetaMessage(String userId, MetaMessage metaMessage);
List<Message> unpackAndClear(String userId);
void refreshMemoryId();
void resetLastUpdatedTime();
long getLastUpdatedTime();
HashMap<String,List<MetaMessage>> getSingleMetaMessageMap();
String getCurrentMemoryId();
@ToCoordinated @ToCoordinated
boolean isSingleUser(); boolean isSingleUser();

View File

@@ -1,72 +1,46 @@
package work.slhaf.partner.core.cognation; package work.slhaf.partner.core.cognation;
import lombok.Data; import com.alibaba.fastjson2.JSONObject;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.api.chat.pojo.MetaMessage;
import work.slhaf.partner.core.cognation.pojo.ActiveData; import work.slhaf.partner.core.PartnerCore;
import work.slhaf.partner.core.submodule.cache.CacheCore;
import work.slhaf.partner.core.submodule.memory.MemoryCore;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.core.submodule.perceive.PerceiveCore;
import java.io.*; import java.io.IOException;
import java.nio.file.Files; import java.io.Serial;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data
@Slf4j @Slf4j
@CapabilityCore(value = "cognation") @CapabilityCore(value = "cognation")
public class CognationCore extends PersistableObject { @Getter
@Setter
public class CognationCore extends PartnerCore<CognationCore> {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String STORAGE_DIR = "./data/memory/"; private final ReentrantLock messageLock = new ReentrantLock();
private static volatile CognationCore cognationCore;
private MemoryCore memoryCore = new MemoryCore();
private CacheCore cacheCore = new CacheCore();
private PerceiveCore perceiveCore = new PerceiveCore();
private ReentrantLock messageLock = new ReentrantLock();
private ActiveData activeData;
/** /**
* 主模型的聊天记录 * 主模型的聊天记录
*/ */
private List<Message> chatMessages = new ArrayList<>(); private List<Message> chatMessages = new ArrayList<>();
private HashMap<String /*startUserId*/, List<MetaMessage>> singleMetaMessageMap = new HashMap<>();
private String currentMemoryId;
private long lastUpdatedTime;
public CognationCore() throws IOException, ClassNotFoundException { public CognationCore() throws IOException, ClassNotFoundException {
createStorageDirectory();
Path filePath = getFilePath("partner");
if (Files.exists(filePath)) {
setupData(this);
} else {
FileUtils.createParentDirectories(filePath.toFile().getParentFile());
connectCores(this);
this.activeData = new ActiveData();
this.serialize();
}
setupHook(this);
log.info("CognationCore注册完毕...");
}
private void connectCores(CognationCore temp) {
temp.setCacheCore(CacheCore.getInstance());
temp.setMemoryCore(MemoryCore.getInstance());
temp.setPerceiveCore(PerceiveCore.getInstance());
} }
@CapabilityMethod @CapabilityMethod
@@ -74,76 +48,26 @@ public class CognationCore extends PersistableObject {
return chatMessages; return chatMessages;
} }
@CapabilityMethod
public long getLastUpdatedTime(){
return lastUpdatedTime;
}
@CapabilityMethod
public HashMap<String,List<MetaMessage>> getSingleMetaMessageMap(){
return singleMetaMessageMap;
}
@CapabilityMethod
public String getCurrentMemoryId(){
return currentMemoryId;
}
@CapabilityMethod @CapabilityMethod
public void setChatMessages(List<Message> chatMessages) { public void setChatMessages(List<Message> chatMessages) {
this.chatMessages = chatMessages; this.chatMessages = chatMessages;
} }
private void setupHook(CognationCore temp) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
temp.serialize();
log.info("[CognationCore] CognationCore已保存");
} catch (IOException e) {
log.error("[CognationCore] CognationCore保存失败: ", e);
}
}));
}
private void setupData(CognationCore temp) throws IOException, ClassNotFoundException {
CognationCore deserialize = deserialize();
temp.activeData = deserialize.activeData;
temp.memoryCore = deserialize.memoryCore;
temp.cacheCore = deserialize.cacheCore;
temp.perceiveCore = deserialize.perceiveCore;
temp.chatMessages = deserialize.chatMessages;
}
public static CognationCore getInstance() {
return cognationCore;
}
public void serialize() throws IOException {
//先写入到临时文件,如果正常写入则覆盖原文件
Path filePath = getFilePath("partner-temp");
Files.createDirectories(Path.of(STORAGE_DIR));
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()));
oos.writeObject(this);
oos.close();
Path path = getFilePath("partner");
Files.move(filePath, path, StandardCopyOption.REPLACE_EXISTING);
log.info("CognationCore 已保存到: {}", path);
} catch (IOException e) {
Files.delete(filePath);
log.error("序列化保存失败: {}", e.getMessage());
}
}
private static CognationCore deserialize() throws IOException, ClassNotFoundException {
Path filePath = getFilePath("partner");
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(filePath.toFile()))) {
CognationCore graph = (CognationCore) ois.readObject();
log.info("CognationCore 已从文件加载: {}", filePath);
return graph;
}
}
private static Path getFilePath(String s) {
return Paths.get(STORAGE_DIR, s + ".memory");
}
private static void createStorageDirectory() {
try {
Files.createDirectories(Paths.get(STORAGE_DIR));
} catch (IOException e) {
System.err.println("创建存储目录失败: " + e.getMessage());
}
}
@CapabilityMethod @CapabilityMethod
public void cleanMessage(List<Message> messages) { public void cleanMessage(List<Message> messages) {
messageLock.lock(); messageLock.lock();
@@ -152,45 +76,46 @@ public class CognationCore extends PersistableObject {
} }
@CapabilityMethod
public void updateActivatedSlices(String userId, List<EvaluatedSlice> memorySlices) {
activeData.updateActivatedSlices(userId, memorySlices);
log.debug("[CoordinatedManager] 已更新激活切片, userId: {}", userId);
}
@CapabilityMethod
public String getActivatedSlicesStr(String userId) {
return activeData.getActivatedSlicesStr(userId);
}
@CapabilityMethod
public HashMap<String, List<EvaluatedSlice>> getActivatedSlices() {
return activeData.getActivatedSlices();
}
@CapabilityMethod
public void clearActivatedSlices(String userId) {
activeData.clearActivatedSlices(userId);
}
@CapabilityMethod
public boolean hasActivatedSlices(String userId) {
return activeData.hasActivatedSlices(userId);
}
@CapabilityMethod
public int getActivatedSlicesSize(String userId) {
return activeData.getActivatedSlices().get(userId).size();
}
@CapabilityMethod
public List<EvaluatedSlice> getActivatedSlices(String userId) {
return activeData.getActivatedSlices().get(userId);
}
@CapabilityMethod @CapabilityMethod
public Lock getMessageLock() { public Lock getMessageLock() {
return messageLock; return messageLock;
} }
}
@CapabilityMethod
public void addMetaMessage(String userId, MetaMessage metaMessage) {
log.debug("[{}] 当前会话历史: {}", JSONObject.toJSONString(singleMetaMessageMap));
if (singleMetaMessageMap.containsKey(userId)) {
singleMetaMessageMap.get(userId).add(metaMessage);
} else {
singleMetaMessageMap.put(userId, new java.util.ArrayList<>());
singleMetaMessageMap.get(userId).add(metaMessage);
}
log.debug("[SessionManager] 会话历史更新: {}", JSONObject.toJSONString(singleMetaMessageMap));
}
@CapabilityMethod
public List<Message> unpackAndClear(String userId) {
List<Message> messages = new ArrayList<>();
for (MetaMessage metaMessage : singleMetaMessageMap.get(userId)) {
messages.add(metaMessage.getUserMessage());
messages.add(metaMessage.getAssistantMessage());
}
singleMetaMessageMap.remove(userId);
return messages;
}
@CapabilityMethod
public void refreshMemoryId() {
currentMemoryId = UUID.randomUUID().toString();
}
@CapabilityMethod
public void resetLastUpdatedTime() {
lastUpdatedTime = System.currentTimeMillis();
}
@Override
protected String getCoreKey() {
return "cognation-core";
}
}

View File

@@ -3,7 +3,7 @@ package work.slhaf.partner.core.cognation.pojo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.api.common.entity.PersistableObject;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import java.io.Serial; import java.io.Serial;
import java.util.HashMap; import java.util.HashMap;

View File

@@ -1,9 +1,9 @@
package work.slhaf.partner.core.submodule.memory; package work.slhaf.partner.core.memory;
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
import work.slhaf.partner.api.agent.factory.capability.annotation.ToCoordinated; import work.slhaf.partner.api.agent.factory.capability.annotation.ToCoordinated;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;

View File

@@ -1,17 +1,18 @@
package work.slhaf.partner.core.submodule.memory; package work.slhaf.partner.core.memory;
import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.core.PartnerCore;
import work.slhaf.partner.core.submodule.memory.exception.UnExistedDateIndexException; import work.slhaf.partner.core.memory.exception.UnExistedDateIndexException;
import work.slhaf.partner.core.submodule.memory.exception.UnExistedTopicException; import work.slhaf.partner.core.memory.exception.UnExistedTopicException;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySliceResult; import work.slhaf.partner.core.memory.pojo.MemorySliceResult;
import work.slhaf.partner.core.submodule.memory.pojo.node.MemoryNode; import work.slhaf.partner.core.memory.pojo.node.MemoryNode;
import work.slhaf.partner.core.submodule.memory.pojo.node.TopicNode; import work.slhaf.partner.core.memory.pojo.node.TopicNode;
import java.io.IOException; import java.io.IOException;
import java.io.Serial; import java.io.Serial;
@@ -21,13 +22,13 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data
@CapabilityCore(value = "memory") @CapabilityCore(value = "memory")
public class MemoryCore extends PersistableObject { @Getter
@Setter
public class MemoryCore extends PartnerCore<MemoryCore> {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static MemoryCore memoryCore;
/** /**
* key: 根主题名称 value: 根主题节点 * key: 根主题名称 value: 根主题节点
@@ -57,13 +58,9 @@ public class MemoryCore extends PersistableObject {
private HashMap<String,List<String>> userIndex = new HashMap<>(); private HashMap<String,List<String>> userIndex = new HashMap<>();
public MemoryCore(){ public MemoryCore() throws IOException, ClassNotFoundException {
memoryCore = this;
} }
public static MemoryCore getInstance() {
return memoryCore;
}
public MemoryResult selectMemory(LocalDate date) throws IOException, ClassNotFoundException { public MemoryResult selectMemory(LocalDate date) throws IOException, ClassNotFoundException {
MemoryResult memoryResult = new MemoryResult(); MemoryResult memoryResult = new MemoryResult();
@@ -328,6 +325,11 @@ public class MemoryCore extends PersistableObject {
@CapabilityMethod @CapabilityMethod
public void cleanSelectedSliceFilter() { public void cleanSelectedSliceFilter() {
this.getSelectedSlices().clear(); this.selectedSlices.clear();
}
@Override
protected String getCoreKey() {
return "memory-core";
} }
} }

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.exception; package work.slhaf.partner.core.memory.exception;
public class NullSliceListException extends RuntimeException { public class NullSliceListException extends RuntimeException {
public NullSliceListException(String message) { public NullSliceListException(String message) {

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.exception; package work.slhaf.partner.core.memory.exception;
public class UnExistedDateIndexException extends RuntimeException { public class UnExistedDateIndexException extends RuntimeException {
public UnExistedDateIndexException(String message) { public UnExistedDateIndexException(String message) {

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.exception; package work.slhaf.partner.core.memory.exception;
public class UnExistedTopicException extends RuntimeException { public class UnExistedTopicException extends RuntimeException {
public UnExistedTopicException(String message) { public UnExistedTopicException(String message) {

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.pojo; package work.slhaf.partner.core.memory.pojo;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.pojo; package work.slhaf.partner.core.memory.pojo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.pojo; package work.slhaf.partner.core.memory.pojo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.pojo; package work.slhaf.partner.core.memory.pojo;
import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data; import lombok.Data;

View File

@@ -1,11 +1,11 @@
package work.slhaf.partner.core.submodule.memory.pojo.node; package work.slhaf.partner.core.memory.pojo.node;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.api.common.entity.PersistableObject;
import work.slhaf.partner.core.submodule.memory.exception.NullSliceListException; import work.slhaf.partner.core.memory.exception.NullSliceListException;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import java.io.*; import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.memory.pojo.node; package work.slhaf.partner.core.memory.pojo.node;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@@ -1,7 +1,7 @@
package work.slhaf.partner.core.submodule.perceive; package work.slhaf.partner.core.perceive;
import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; import work.slhaf.partner.api.agent.factory.capability.annotation.Capability;
import work.slhaf.partner.core.submodule.perceive.pojo.User; import work.slhaf.partner.core.perceive.pojo.User;
@Capability(value = "perceive") @Capability(value = "perceive")
public interface PerceiveCapability { public interface PerceiveCapability {

View File

@@ -1,13 +1,15 @@
package work.slhaf.partner.core.submodule.perceive; package work.slhaf.partner.core.perceive;
import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore;
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.core.PartnerCore;
import work.slhaf.partner.core.cognation.exception.UserNotExistsException; import work.slhaf.partner.core.cognation.exception.UserNotExistsException;
import work.slhaf.partner.core.submodule.perceive.pojo.User; import work.slhaf.partner.core.perceive.pojo.User;
import java.io.IOException;
import java.io.Serial; import java.io.Serial;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -16,13 +18,13 @@ import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data
@CapabilityCore(value = "perceive") @CapabilityCore(value = "perceive")
public class PerceiveCore extends PersistableObject { @Getter
@Setter
public class PerceiveCore extends PartnerCore<PerceiveCore> {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static volatile PerceiveCore perceiveCore;
private static final ReentrantLock usersLock = new ReentrantLock(); private static final ReentrantLock usersLock = new ReentrantLock();
/** /**
@@ -30,12 +32,7 @@ public class PerceiveCore extends PersistableObject {
*/ */
private List<User> users = new ArrayList<>(); private List<User> users = new ArrayList<>();
public PerceiveCore() { public PerceiveCore() throws IOException, ClassNotFoundException {
perceiveCore = this;
}
public static PerceiveCore getInstance() {
return perceiveCore;
} }
@CapabilityMethod @CapabilityMethod
@@ -94,4 +91,9 @@ public class PerceiveCore extends PersistableObject {
user.updateRelationChange(user.getRelationChange()); user.updateRelationChange(user.getRelationChange());
usersLock.unlock(); usersLock.unlock();
} }
@Override
protected String getCoreKey() {
return "perceive-core";
}
} }

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.core.submodule.perceive.pojo; package work.slhaf.partner.core.perceive.pojo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

View File

@@ -1,4 +0,0 @@
package work.slhaf.partner.core.submodule.dispatch;
public interface DispatchCapability {
}

View File

@@ -1,32 +0,0 @@
package work.slhaf.partner.core.submodule.dispatch;
import work.slhaf.partner.api.common.entity.PersistableObject;
import work.slhaf.partner.core.submodule.dispatch.pojo.DispatchData;
import java.io.Serial;
public class DispatchCore extends PersistableObject {
@Serial
private static final long serialVersionUID = 1L;
public static volatile DispatchCore dispatchCore;
public static DispatchCore getInstance() {
if (dispatchCore == null) {
synchronized (DispatchCore.class) {
if (dispatchCore == null) {
dispatchCore = new DispatchCore();
}
}
}
return dispatchCore;
}
public void dispatch(DispatchData dispatchData){
}
public void listDispatchData(){
}
}

View File

@@ -1,15 +0,0 @@
package work.slhaf.partner.core.submodule.dispatch.pojo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class DispatchData {
private LocalDateTime dateTime;
private String userId;
private String comment;
//TODO 替换为<执行器>或者<插件>
private String executor;
}

View File

@@ -10,12 +10,12 @@ public abstract class PostRunningModule extends AgentRunningModule<PartnerRunnin
@Override @Override
public final void execute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException { public final void execute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException {
boolean trigger = context.getModuleContext().getExtraContext().getBoolean("post_process_trigger"); boolean trigger = context.getModuleContext().getExtraContext().getBoolean("post_process_trigger");
if (!trigger){ if (!trigger) {
return; return;
} }
doExecute(context); doExecute(context);
} }
protected void doExecute(PartnerRunningFlowContext context){} public abstract void doExecute(PartnerRunningFlowContext context);
} }

View File

@@ -13,7 +13,7 @@ import java.util.HashMap;
*/ */
@Slf4j @Slf4j
public abstract class PreRunningModule extends AgentRunningModule<PartnerRunningFlowContext> { public abstract class PreRunningModule extends AgentRunningModule<PartnerRunningFlowContext> {
private void setAppendedPrompt(PartnerRunningFlowContext context) { private synchronized void setAppendedPrompt(PartnerRunningFlowContext context) {
AppendPromptData data = new AppendPromptData(); AppendPromptData data = new AppendPromptData();
data.setModuleName(moduleName()); data.setModuleName(moduleName());
HashMap<String, String> map = getPromptDataMap(context.getUserId()); HashMap<String, String> map = getPromptDataMap(context.getUserId());
@@ -21,12 +21,15 @@ public abstract class PreRunningModule extends AgentRunningModule<PartnerRunning
context.setAppendedPrompt(data); context.setAppendedPrompt(data);
} }
private void setActiveModule(PartnerRunningFlowContext context) { private synchronized void setActiveModule(PartnerRunningFlowContext context) {
context.getCoreContext().addActiveModule(moduleName()); context.getCoreContext().addActiveModule(moduleName());
} }
protected abstract HashMap<String, String> getPromptDataMap(String userId); protected abstract HashMap<String, String> getPromptDataMap(String userId);
/**
* 用于在CoreModule接收到的模块Prompt中标识模块名称
*/
protected abstract String moduleName(); protected abstract String moduleName();
@Override @Override

View File

@@ -0,0 +1,46 @@
package work.slhaf.partner.module.modules.action.planner;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
import work.slhaf.partner.module.common.module.PreRunningModule;
import work.slhaf.partner.module.modules.action.planner.evaluator.ActionEvaluator;
import work.slhaf.partner.module.modules.action.planner.extractor.ActionExtractor;
import work.slhaf.partner.module.modules.action.planner.extractor.entity.ExtractorInput;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.io.IOException;
import java.util.HashMap;
/**
* 负责针对本次输入生成基础的行动建议,是否执行由主模型判断。
*/
@AgentModule(name = "task_planner",order = 2)
public class ActionPlanner extends PreRunningModule {
@InjectModule
private ActionEvaluator actionEvaluator;
@InjectModule
private ActionExtractor actionExtractor;
@Override
protected void doExecute(PartnerRunningFlowContext context) throws IOException, ClassNotFoundException {
ExtractorInput extractorInput = getExtractorInput(context);
}
private ExtractorInput getExtractorInput(PartnerRunningFlowContext context) {
ExtractorInput input = new ExtractorInput();
input.setInput(context.getInput());
input.setRecentMessages();
return input;
}
@Override
protected HashMap<String, String> getPromptDataMap(String userId) {
return null;
}
@Override
protected String moduleName() {
return "task_planner";
}
}

View File

@@ -0,0 +1,27 @@
package work.slhaf.partner.module.modules.action.planner.evaluator;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.action.planner.evaluator.entity.EvaluatorResult;
@AgentSubModule
public class ActionEvaluator extends AgentRunningSubModule<EvaluatorInput, EvaluatorResult> implements ActivateModel {
@Override
public EvaluatorResult execute(EvaluatorInput data) {
return null;
}
@Override
public String modelKey() {
return "action_evaluator";
}
@Override
public boolean withBasicPrompt() {
return true;
}
}

View File

@@ -0,0 +1,11 @@
package work.slhaf.partner.module.modules.action.planner.evaluator.entity;
import lombok.Data;
import java.util.List;
@Data
public class EvaluatorInput {
private List<String> recentMessages;
private String tendency;
}

View File

@@ -0,0 +1,13 @@
package work.slhaf.partner.module.modules.action.planner.evaluator.entity;
import lombok.Data;
import work.slhaf.partner.core.action.entity.ActionData;
import work.slhaf.partner.core.action.entity.ActionType;
@Data
public class EvaluatorResult {
private boolean ok;
private ActionType type;
private String typeInfo;
private ActionData actionData;
}

View File

@@ -0,0 +1,27 @@
package work.slhaf.partner.module.modules.action.planner.extractor;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.module.modules.action.planner.extractor.entity.ExtractorInput;
import work.slhaf.partner.module.modules.action.planner.extractor.entity.ExtractorResult;
@AgentSubModule
public class ActionExtractor extends AgentRunningSubModule<ExtractorInput, ExtractorResult> implements ActivateModel {
@Override
public ExtractorResult execute(ExtractorInput data) {
return null;
}
@Override
public String modelKey() {
return "action_extractor";
}
@Override
public boolean withBasicPrompt() {
return false;
}
}

View File

@@ -0,0 +1,12 @@
package work.slhaf.partner.module.modules.action.planner.extractor.entity;
import lombok.Data;
import work.slhaf.partner.api.chat.pojo.Message;
import java.util.List;
@Data
public class ExtractorInput {
private String input;
private List<Message> recentMessages;
}

View File

@@ -0,0 +1,9 @@
package work.slhaf.partner.module.modules.action.planner.extractor.entity;
import lombok.Data;
@Data
public class ExtractorResult {
private boolean action;
private String tendency;
}

View File

@@ -0,0 +1,4 @@
package work.slhaf.partner.module.modules.action.scheduler;
public class ActionDispatcher {
}

View File

@@ -0,0 +1,7 @@
package work.slhaf.partner.module.modules.action.scheduler;
/**
* 负责综合前置模块
*/
public class TaskScheduler {
}

View File

@@ -17,7 +17,6 @@ import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.module.common.entity.AppendPromptData; import work.slhaf.partner.module.common.entity.AppendPromptData;
import work.slhaf.partner.module.common.model.ModelConstant; import work.slhaf.partner.module.common.model.ModelConstant;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import work.slhaf.partner.runtime.session.SessionManager;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@@ -34,7 +33,6 @@ public class CoreModel extends AgentRunningModule<PartnerRunningFlowContext> imp
@InjectCapability @InjectCapability
private CognationCapability cognationCapability; private CognationCapability cognationCapability;
private SessionManager sessionManager;
private List<Message> appendedMessages; private List<Message> appendedMessages;
@Init @Init
@@ -42,7 +40,6 @@ public class CoreModel extends AgentRunningModule<PartnerRunningFlowContext> imp
List<Message> chatMessages = this.cognationCapability.getChatMessages(); List<Message> chatMessages = this.cognationCapability.getChatMessages();
this.getModel().setChatMessages(chatMessages); this.getModel().setChatMessages(chatMessages);
this.appendedMessages = new ArrayList<>(); this.appendedMessages = new ArrayList<>();
this.sessionManager = SessionManager.getInstance();
updateChatClientSettings(); updateChatClientSettings();
log.info("[CoreModel] CoreModel注册完毕..."); log.info("[CoreModel] CoreModel注册完毕...");
@@ -181,7 +178,7 @@ public class CoreModel extends AgentRunningModule<PartnerRunningFlowContext> imp
//区分单人聊天场景 //区分单人聊天场景
if (runningFlowContext.isSingle()) { if (runningFlowContext.isSingle()) {
MetaMessage metaMessage = new MetaMessage(primaryUserMessage, assistantMessage); MetaMessage metaMessage = new MetaMessage(primaryUserMessage, assistantMessage);
sessionManager.addMetaMessage(runningFlowContext.getUserId(), metaMessage); cognationCapability.addMetaMessage(runningFlowContext.getUserId(), metaMessage);
} }
} }

View File

@@ -7,20 +7,20 @@ import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule; import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
import work.slhaf.partner.core.cache.CacheCapability;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.cache.CacheCapability; import work.slhaf.partner.core.memory.MemoryCapability;
import work.slhaf.partner.core.submodule.memory.MemoryCapability; import work.slhaf.partner.core.memory.exception.UnExistedDateIndexException;
import work.slhaf.partner.core.submodule.memory.exception.UnExistedDateIndexException; import work.slhaf.partner.core.memory.exception.UnExistedTopicException;
import work.slhaf.partner.core.submodule.memory.exception.UnExistedTopicException; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice;
import work.slhaf.partner.module.common.module.PreRunningModule; import work.slhaf.partner.module.common.module.PreRunningModule;
import work.slhaf.partner.module.modules.memory.selector.evaluator.SliceSelectEvaluator; import work.slhaf.partner.module.modules.memory.selector.evaluator.SliceSelectEvaluator;
import work.slhaf.partner.module.modules.memory.selector.evaluator.data.EvaluatorInput; import work.slhaf.partner.module.modules.memory.selector.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.memory.selector.extractor.MemorySelectExtractor; import work.slhaf.partner.module.modules.memory.selector.extractor.MemorySelectExtractor;
import work.slhaf.partner.module.modules.memory.selector.extractor.data.ExtractorMatchData; import work.slhaf.partner.module.modules.memory.selector.extractor.entity.ExtractorMatchData;
import work.slhaf.partner.module.modules.memory.selector.extractor.data.ExtractorResult; import work.slhaf.partner.module.modules.memory.selector.extractor.entity.ExtractorResult;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.io.IOException; import java.io.IOException;
@@ -33,7 +33,7 @@ import java.util.List;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Data @Data
@Slf4j @Slf4j
@AgentModule(name="memory_selector",order=1) @AgentModule(name="memory_selector",order=2)
public class MemorySelector extends PreRunningModule { public class MemorySelector extends PreRunningModule {
@InjectCapability @InjectCapability
@@ -54,9 +54,9 @@ public class MemorySelector extends PreRunningModule {
//获取主题路径 //获取主题路径
ExtractorResult extractorResult = memorySelectExtractor.execute(runningFlowContext); ExtractorResult extractorResult = memorySelectExtractor.execute(runningFlowContext);
if (extractorResult.isRecall() || !extractorResult.getMatches().isEmpty()) { if (extractorResult.isRecall() || !extractorResult.getMatches().isEmpty()) {
cognationCapability.clearActivatedSlices(userId); cacheCapability.clearActivatedSlices(userId);
List<EvaluatedSlice> evaluatedSlices = selectAndEvaluateMemory(runningFlowContext, extractorResult); List<EvaluatedSlice> evaluatedSlices = selectAndEvaluateMemory(runningFlowContext, extractorResult);
cognationCapability.updateActivatedSlices(userId, evaluatedSlices); cacheCapability.updateActivatedSlices(userId, evaluatedSlices);
} }
setModuleContextRecall(runningFlowContext); setModuleContextRecall(runningFlowContext);
} }
@@ -81,10 +81,10 @@ public class MemorySelector extends PreRunningModule {
private void setModuleContextRecall(PartnerRunningFlowContext runningFlowContext) { private void setModuleContextRecall(PartnerRunningFlowContext runningFlowContext) {
String userId = runningFlowContext.getUserId(); String userId = runningFlowContext.getUserId();
boolean recall = cognationCapability.hasActivatedSlices(userId); boolean recall = cacheCapability.hasActivatedSlices(userId);
runningFlowContext.getModuleContext().getExtraContext().put("recall", recall); runningFlowContext.getModuleContext().getExtraContext().put("recall", recall);
if (recall) { if (recall) {
runningFlowContext.getModuleContext().getExtraContext().put("recall_count", cognationCapability.getActivatedSlicesSize(userId)); runningFlowContext.getModuleContext().getExtraContext().put("recall_count", cacheCapability.getActivatedSlicesSize(userId));
} }
} }
@@ -148,7 +148,7 @@ public class MemorySelector extends PreRunningModule {
map.put("[用户记忆缓存] <与最新一条消息的发送者的近两天对话记忆印象, 可能与[记忆缓存]稍有重复>", userDialogMapStr); map.put("[用户记忆缓存] <与最新一条消息的发送者的近两天对话记忆印象, 可能与[记忆缓存]稍有重复>", userDialogMapStr);
} }
String sliceStr = cognationCapability.getActivatedSlicesStr(userId); String sliceStr = cacheCapability.getActivatedSlicesStr(userId);
if (sliceStr != null && !sliceStr.isEmpty()) { if (sliceStr != null && !sliceStr.isEmpty()) {
map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来()>", sliceStr); map.put("[记忆切片] <你与最新一条消息的发送者的相关回忆, 不会与[记忆缓存]重复, 如果有重复你也可以指出来()>", sliceStr);
} }

View File

@@ -11,14 +11,14 @@ 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.ActivateModel;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor; import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySliceResult; import work.slhaf.partner.core.memory.pojo.MemorySliceResult;
import work.slhaf.partner.module.modules.memory.selector.evaluator.data.EvaluatorBatchInput; import work.slhaf.partner.module.modules.memory.selector.evaluator.entity.EvaluatorBatchInput;
import work.slhaf.partner.module.modules.memory.selector.evaluator.data.EvaluatorInput; import work.slhaf.partner.module.modules.memory.selector.evaluator.entity.EvaluatorInput;
import work.slhaf.partner.module.modules.memory.selector.evaluator.data.EvaluatorResult; import work.slhaf.partner.module.modules.memory.selector.evaluator.entity.EvaluatorResult;
import work.slhaf.partner.module.modules.memory.selector.evaluator.data.SliceSummary; import work.slhaf.partner.module.modules.memory.selector.evaluator.entity.SliceSummary;
import java.util.*; import java.util.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.selector.evaluator.data; package work.slhaf.partner.module.modules.memory.selector.evaluator.entity;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -1,9 +1,9 @@
package work.slhaf.partner.module.modules.memory.selector.evaluator.data; package work.slhaf.partner.module.modules.memory.selector.evaluator.entity;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.selector.evaluator.data; package work.slhaf.partner.module.modules.memory.selector.evaluator.entity;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.selector.evaluator.data; package work.slhaf.partner.module.modules.memory.selector.evaluator.entity;
import lombok.Data; import lombok.Data;

View File

@@ -7,21 +7,18 @@ import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; 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.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.ActivateModel;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.api.chat.pojo.MetaMessage; import work.slhaf.partner.api.chat.pojo.MetaMessage;
import work.slhaf.partner.common.exception.callback.GlobalExceptionHandler; import work.slhaf.partner.core.cache.CacheCapability;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.memory.MemoryCapability; import work.slhaf.partner.core.memory.MemoryCapability;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import work.slhaf.partner.module.modules.memory.selector.extractor.data.ExtractorInput; import work.slhaf.partner.module.modules.memory.selector.extractor.entity.ExtractorInput;
import work.slhaf.partner.module.modules.memory.selector.extractor.data.ExtractorMatchData; import work.slhaf.partner.module.modules.memory.selector.extractor.entity.ExtractorMatchData;
import work.slhaf.partner.module.modules.memory.selector.extractor.data.ExtractorResult; import work.slhaf.partner.module.modules.memory.selector.extractor.entity.ExtractorResult;
import work.slhaf.partner.runtime.exception.pojo.GlobalException;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import work.slhaf.partner.runtime.session.SessionManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -40,22 +37,18 @@ public class MemorySelectExtractor extends AgentRunningSubModule<PartnerRunningF
private MemoryCapability memoryCapability; private MemoryCapability memoryCapability;
@InjectCapability @InjectCapability
private CognationCapability cognationCapability; private CognationCapability cognationCapability;
@InjectCapability
private CacheCapability cacheCapability;
private SessionManager sessionManager;
@Init
public void init() {
sessionManager = SessionManager.getInstance();
}
@Override @Override
public ExtractorResult execute(PartnerRunningFlowContext context) { public ExtractorResult execute(PartnerRunningFlowContext context) {
log.debug("[MemorySelectExtractor] 主题提取模块开始..."); log.debug("[MemorySelectExtractor] 主题提取模块开始...");
// 结构化为指定格式 // 结构化为指定格式
List<Message> chatMessages = new ArrayList<>(); List<Message> chatMessages = new ArrayList<>();
List<MetaMessage> metaMessages = sessionManager.getSingleMetaMessageMap().get(context.getUserId()); List<MetaMessage> metaMessages = cognationCapability.getSingleMetaMessageMap().get(context.getUserId());
if (metaMessages == null) { if (metaMessages == null) {
sessionManager.getSingleMetaMessageMap().put(context.getUserId(), new ArrayList<>()); cognationCapability.getSingleMetaMessageMap().put(context.getUserId(), new ArrayList<>());
} else { } else {
for (MetaMessage metaMessage : metaMessages) { for (MetaMessage metaMessage : metaMessages) {
chatMessages.add(metaMessage.getUserMessage()); chatMessages.add(metaMessage.getUserMessage());
@@ -65,7 +58,7 @@ public class MemorySelectExtractor extends AgentRunningSubModule<PartnerRunningF
ExtractorResult extractorResult; ExtractorResult extractorResult;
try { try {
List<EvaluatedSlice> activatedMemorySlices = cognationCapability.getActivatedSlices(context.getUserId()); List<EvaluatedSlice> activatedMemorySlices = cacheCapability.getActivatedSlices(context.getUserId());
ExtractorInput extractorInput = ExtractorInput.builder() ExtractorInput extractorInput = ExtractorInput.builder()
.text(context.getInput()) .text(context.getInput())
.date(context.getDateTime().toLocalDate()) .date(context.getDateTime().toLocalDate())
@@ -79,7 +72,6 @@ public class MemorySelectExtractor extends AgentRunningSubModule<PartnerRunningF
log.debug("[MemorySelectExtractor] 主题提取结果: {}", extractorResult); log.debug("[MemorySelectExtractor] 主题提取结果: {}", extractorResult);
} catch (Exception e) { } catch (Exception e) {
log.error("[MemorySelectExtractor] 主题提取出错: ", e); log.error("[MemorySelectExtractor] 主题提取出错: ", e);
GlobalExceptionHandler.writeExceptionState(new GlobalException(e.getLocalizedMessage()));
extractorResult = new ExtractorResult(); extractorResult = new ExtractorResult();
extractorResult.setRecall(false); extractorResult.setRecall(false);
extractorResult.setMatches(List.of()); extractorResult.setMatches(List.of());

View File

@@ -1,9 +1,9 @@
package work.slhaf.partner.module.modules.memory.selector.extractor.data; package work.slhaf.partner.module.modules.memory.selector.extractor.entity;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.core.submodule.memory.pojo.EvaluatedSlice; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.selector.extractor.data; package work.slhaf.partner.module.modules.memory.selector.extractor.entity;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.selector.extractor.data; package work.slhaf.partner.module.modules.memory.selector.extractor.entity;
import lombok.Data; import lombok.Data;

View File

@@ -11,19 +11,18 @@ import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
import work.slhaf.partner.api.chat.constant.ChatConstant; import work.slhaf.partner.api.chat.constant.ChatConstant;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor; import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
import work.slhaf.partner.core.cache.CacheCapability;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.cache.CacheCapability; import work.slhaf.partner.core.memory.MemoryCapability;
import work.slhaf.partner.core.submodule.memory.MemoryCapability; import work.slhaf.partner.core.memory.pojo.MemorySlice;
import work.slhaf.partner.core.submodule.memory.pojo.MemorySlice; import work.slhaf.partner.core.perceive.PerceiveCapability;
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability;
import work.slhaf.partner.module.common.module.PostRunningModule; import work.slhaf.partner.module.common.module.PostRunningModule;
import work.slhaf.partner.module.modules.memory.updater.summarizer.MultiSummarizer; import work.slhaf.partner.module.modules.memory.updater.summarizer.MultiSummarizer;
import work.slhaf.partner.module.modules.memory.updater.summarizer.SingleSummarizer; import work.slhaf.partner.module.modules.memory.updater.summarizer.SingleSummarizer;
import work.slhaf.partner.module.modules.memory.updater.summarizer.TotalSummarizer; import work.slhaf.partner.module.modules.memory.updater.summarizer.TotalSummarizer;
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeInput; import work.slhaf.partner.module.modules.memory.updater.summarizer.entity.SummarizeInput;
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeResult; import work.slhaf.partner.module.modules.memory.updater.summarizer.entity.SummarizeResult;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import work.slhaf.partner.runtime.session.SessionManager;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
@@ -57,7 +56,6 @@ public class MemoryUpdater extends PostRunningModule {
@InjectModule @InjectModule
private TotalSummarizer totalSummarizer; private TotalSummarizer totalSummarizer;
private SessionManager sessionManager;
private InteractionThreadPoolExecutor executor; private InteractionThreadPoolExecutor executor;
/** /**
* 用于临时存储完整对话记录在MemoryManager的分离后 * 用于临时存储完整对话记录在MemoryManager的分离后
@@ -67,7 +65,6 @@ public class MemoryUpdater extends PostRunningModule {
@Init @Init
public void init() { public void init() {
executor = InteractionThreadPoolExecutor.getInstance(); executor = InteractionThreadPoolExecutor.getInstance();
sessionManager = SessionManager.getInstance();
setScheduledUpdater(); setScheduledUpdater();
} }
@@ -77,13 +74,13 @@ public class MemoryUpdater extends PostRunningModule {
while (!Thread.interrupted()) { while (!Thread.interrupted()) {
try { try {
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
long lastUpdatedTime = sessionManager.getLastUpdatedTime(); long lastUpdatedTime = cognationCapability.getLastUpdatedTime();
int chatCount = cognationCapability.getChatMessages().size(); int chatCount = cognationCapability.getChatMessages().size();
if (lastUpdatedTime != 0 && currentTime - lastUpdatedTime > UPDATE_TRIGGER_INTERVAL && chatCount > 1) { if (lastUpdatedTime != 0 && currentTime - lastUpdatedTime > UPDATE_TRIGGER_INTERVAL && chatCount > 1) {
updateMemory(); updateMemory();
cognationCapability.getChatMessages().clear(); cognationCapability.getChatMessages().clear();
// 重置MemoryId // 重置MemoryId
sessionManager.refreshMemoryId(); cognationCapability.refreshMemoryId();
log.info("[MemoryUpdater] 记忆更新: 自动触发"); log.info("[MemoryUpdater] 记忆更新: 自动触发");
} }
Thread.sleep(SCHEDULED_UPDATE_INTERVAL); Thread.sleep(SCHEDULED_UPDATE_INTERVAL);
@@ -133,7 +130,7 @@ public class MemoryUpdater extends PostRunningModule {
updateSingleChatSlices(singleMemorySummary); updateSingleChatSlices(singleMemorySummary);
// 更新多人场景下的记忆及相关的确定性记忆 // 更新多人场景下的记忆及相关的确定性记忆
updateMultiChatSlices(singleMemorySummary); updateMultiChatSlices(singleMemorySummary);
sessionManager.resetLastUpdatedTime(); cognationCapability.resetLastUpdatedTime();
log.debug("[MemoryUpdater] 记忆更新流程结束..."); log.debug("[MemoryUpdater] 记忆更新流程结束...");
} }
@@ -219,12 +216,12 @@ public class MemoryUpdater extends PostRunningModule {
private void updateSingleChatSlices(HashMap<String, String> singleMemorySummary) { private void updateSingleChatSlices(HashMap<String, String> singleMemorySummary) {
log.debug("[MemoryUpdater] 单聊记忆更新流程开始..."); log.debug("[MemoryUpdater] 单聊记忆更新流程开始...");
// 更新单聊记忆同时从chatMessages中去掉单聊记忆 // 更新单聊记忆同时从chatMessages中去掉单聊记忆
Set<String> userIdSet = new HashSet<>(sessionManager.getSingleMetaMessageMap().keySet()); Set<String> userIdSet = new HashSet<>(cognationCapability.getSingleMetaMessageMap().keySet());
List<Callable<Void>> tasks = new ArrayList<>(); List<Callable<Void>> tasks = new ArrayList<>();
// 多人聊天? // 多人聊天?
AtomicInteger count = new AtomicInteger(0); AtomicInteger count = new AtomicInteger(0);
for (String id : userIdSet) { for (String id : userIdSet) {
List<Message> messages = sessionManager.unpackAndClear(id); List<Message> messages = cognationCapability.unpackAndClear(id);
tasks.add(() -> { tasks.add(() -> {
int thisCount = count.incrementAndGet(); int thisCount = count.incrementAndGet();
log.debug("[MemoryUpdater] 单聊记忆[{}]更新: {}", thisCount, id); log.debug("[MemoryUpdater] 单聊记忆[{}]更新: {}", thisCount, id);
@@ -262,7 +259,7 @@ public class MemoryUpdater extends PostRunningModule {
private MemorySlice getMemorySlice(String userId, SummarizeResult summarizeResult, List<Message> chatMessages) { private MemorySlice getMemorySlice(String userId, SummarizeResult summarizeResult, List<Message> chatMessages) {
MemorySlice memorySlice = new MemorySlice(); MemorySlice memorySlice = new MemorySlice();
// 设置 memoryId,timestamp // 设置 memoryId,timestamp
memorySlice.setMemoryId(sessionManager.getCurrentMemoryId()); memorySlice.setMemoryId(cognationCapability.getCurrentMemoryId());
memorySlice.setTimestamp(System.currentTimeMillis()); memorySlice.setTimestamp(System.currentTimeMillis());
// 补充信息 // 补充信息

View File

@@ -10,8 +10,8 @@ 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.ActivateModel;
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.api.chat.pojo.ChatResponse; 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.entity.SummarizeInput;
import work.slhaf.partner.module.modules.memory.updater.summarizer.data.SummarizeResult; import work.slhaf.partner.module.modules.memory.updater.summarizer.entity.SummarizeResult;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.updater.summarizer.data; package work.slhaf.partner.module.modules.memory.updater.summarizer.entity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.memory.updater.summarizer.data; package work.slhaf.partner.module.modules.memory.updater.summarizer.entity;
import lombok.Data; import lombok.Data;

View File

@@ -4,8 +4,8 @@ import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule; import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability; import work.slhaf.partner.core.perceive.PerceiveCapability;
import work.slhaf.partner.core.submodule.perceive.pojo.User; import work.slhaf.partner.core.perceive.pojo.User;
import work.slhaf.partner.module.common.module.PreRunningModule; import work.slhaf.partner.module.common.module.PreRunningModule;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;

View File

@@ -9,11 +9,11 @@ import work.slhaf.partner.api.agent.factory.module.annotation.Init;
import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule;
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor; import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability; import work.slhaf.partner.core.perceive.PerceiveCapability;
import work.slhaf.partner.core.submodule.perceive.pojo.User; import work.slhaf.partner.core.perceive.pojo.User;
import work.slhaf.partner.module.common.module.PostRunningModule; import work.slhaf.partner.module.common.module.PostRunningModule;
import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.RelationExtractor; import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.RelationExtractor;
import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.pojo.RelationExtractResult; import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.entity.RelationExtractResult;
import work.slhaf.partner.module.modules.perceive.updater.static_extractor.StaticMemoryExtractor; import work.slhaf.partner.module.modules.perceive.updater.static_extractor.StaticMemoryExtractor;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
@@ -29,7 +29,7 @@ import java.util.concurrent.locks.ReentrantLock;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@Slf4j @Slf4j
@Data @Data
@AgentModule(name = "perceive_updater", order = 8) @AgentModule(name = "perceive_updater", order = 7)
public class PerceiveUpdater extends PostRunningModule { public class PerceiveUpdater extends PostRunningModule {
private static volatile PerceiveUpdater perceiveUpdater; private static volatile PerceiveUpdater perceiveUpdater;

View File

@@ -10,10 +10,10 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunn
import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.api.chat.pojo.ChatResponse;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability; import work.slhaf.partner.core.perceive.PerceiveCapability;
import work.slhaf.partner.core.submodule.perceive.pojo.User; import work.slhaf.partner.core.perceive.pojo.User;
import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.pojo.RelationExtractInput; import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.entity.RelationExtractInput;
import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.pojo.RelationExtractResult; import work.slhaf.partner.module.modules.perceive.updater.relation_extractor.entity.RelationExtractResult;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.perceive.updater.relation_extractor.pojo; package work.slhaf.partner.module.modules.perceive.updater.relation_extractor.entity;
import lombok.Data; import lombok.Data;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.perceive.updater.relation_extractor.pojo; package work.slhaf.partner.module.modules.perceive.updater.relation_extractor.entity;
import lombok.Data; import lombok.Data;

View File

@@ -10,8 +10,8 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateM
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule;
import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.api.chat.pojo.ChatResponse;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability; import work.slhaf.partner.core.perceive.PerceiveCapability;
import work.slhaf.partner.module.modules.perceive.updater.static_extractor.data.StaticMemoryExtractInput; import work.slhaf.partner.module.modules.perceive.updater.static_extractor.entity.StaticMemoryExtractInput;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import java.util.HashMap; import java.util.HashMap;

View File

@@ -1,4 +1,4 @@
package work.slhaf.partner.module.modules.perceive.updater.static_extractor.data; package work.slhaf.partner.module.modules.perceive.updater.static_extractor.entity;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

View File

@@ -5,14 +5,12 @@ import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule; import work.slhaf.partner.api.agent.factory.module.annotation.AgentModule;
import work.slhaf.partner.api.agent.factory.module.annotation.Init;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.core.submodule.perceive.PerceiveCapability; import work.slhaf.partner.core.perceive.PerceiveCapability;
import work.slhaf.partner.core.submodule.perceive.pojo.User; import work.slhaf.partner.core.perceive.pojo.User;
import work.slhaf.partner.module.common.module.PreRunningModule; import work.slhaf.partner.module.common.module.PreRunningModule;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import work.slhaf.partner.runtime.interaction.data.context.subcontext.CoreContext; import work.slhaf.partner.runtime.interaction.data.context.subcontext.CoreContext;
import work.slhaf.partner.runtime.session.SessionManager;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@@ -30,12 +28,6 @@ public class PreprocessExecutor extends PreRunningModule {
private CognationCapability cognationCapability; private CognationCapability cognationCapability;
@InjectCapability @InjectCapability
private PerceiveCapability perceiveCapability; private PerceiveCapability perceiveCapability;
private SessionManager sessionManager;
@Init
public void init() {
this.sessionManager = SessionManager.getInstance();
}
@Override @Override
public void doExecute(PartnerRunningFlowContext context) { public void doExecute(PartnerRunningFlowContext context) {
@@ -44,9 +36,9 @@ public class PreprocessExecutor extends PreRunningModule {
} }
private void checkAndSetMemoryId() { private void checkAndSetMemoryId() {
String currentMemoryId = sessionManager.getCurrentMemoryId(); String currentMemoryId = cognationCapability.getCurrentMemoryId();
if (currentMemoryId == null || cognationCapability.getChatMessages().isEmpty()) { if (currentMemoryId == null || cognationCapability.getChatMessages().isEmpty()) {
sessionManager.refreshMemoryId(); cognationCapability.refreshMemoryId();
} }
} }

View File

@@ -1,21 +0,0 @@
package work.slhaf.partner.module.modules.task;
import lombok.Data;
@Data
public class TaskEvaluator {
private static TaskEvaluator taskEvaluator;
private TaskEvaluator (){}
public static TaskEvaluator getInstance() {
if (taskEvaluator == null) {
taskEvaluator = new TaskEvaluator();
}
return taskEvaluator;
}
protected String modelKey() {
return "task_evaluator";
}
}

View File

@@ -1,20 +0,0 @@
package work.slhaf.partner.module.modules.task;
import lombok.Data;
import work.slhaf.partner.common.thread.InteractionThreadPoolExecutor;
@Data
public class TaskExecutor {
private static TaskExecutor taskExecutor;
private InteractionThreadPoolExecutor executor;
private TaskExecutor(){}
public static TaskExecutor getInstance(){
if (taskExecutor == null){
taskExecutor = new TaskExecutor();
taskExecutor.setExecutor(InteractionThreadPoolExecutor.getInstance());
}
return taskExecutor;
}
}

View File

@@ -1,27 +0,0 @@
package work.slhaf.partner.module.modules.task;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
@Data
@Slf4j
public class TaskScheduler {
private static TaskScheduler taskScheduler;
private TaskScheduler() {
}
public static TaskScheduler getInstance() {
if (taskScheduler == null) {
taskScheduler = new TaskScheduler();
log.info("TaskScheduler注册完毕...");
}
return taskScheduler;
}
public void execute(PartnerRunningFlowContext runningFlowContext) {
}
}

View File

@@ -1,31 +0,0 @@
package work.slhaf.partner.module.modules.task.data;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class TaskData implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String id;
/**
* 执行类别: 即时任务/定时任务
*/
private String executeType;
/**
* cron表达式仅定时任务需要填写
*/
private String cronStr;
private String comment;
public static class Constant {
public static final String CURRENT = "current";
public static final String SCHEDULE = "schedule";
}
}

View File

@@ -3,9 +3,7 @@ package work.slhaf.partner.runtime.exception.pojo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import work.slhaf.partner.api.common.entity.PersistableObject; import work.slhaf.partner.api.common.entity.PersistableObject;
import work.slhaf.partner.core.cognation.CognationCore;
import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext; import work.slhaf.partner.runtime.interaction.data.context.PartnerRunningFlowContext;
import work.slhaf.partner.runtime.session.SessionManager;
import java.io.Serial; import java.io.Serial;
import java.util.HashMap; import java.util.HashMap;
@@ -20,7 +18,5 @@ public class GlobalExceptionData extends PersistableObject {
private String exceptionMessage; private String exceptionMessage;
protected HashMap<String, PartnerRunningFlowContext> context = PartnerRunningFlowContext.getInstance(); protected HashMap<String, PartnerRunningFlowContext> context = PartnerRunningFlowContext.getInstance();
protected SessionManager sessionManager = SessionManager.getInstance();
protected CognationCore cognationCore = CognationCore.getInstance();
protected Long exceptionTime = System.currentTimeMillis(); protected Long exceptionTime = System.currentTimeMillis();
} }

View File

@@ -10,12 +10,20 @@ public class PartnerInteractionAdapter extends AgentInteractionAdapter<PartnerIn
protected PartnerOutputData parseOutputData(PartnerRunningFlowContext outputContext) { protected PartnerOutputData parseOutputData(PartnerRunningFlowContext outputContext) {
PartnerOutputData outputData = new PartnerOutputData(); PartnerOutputData outputData = new PartnerOutputData();
outputData.setCode(outputContext.getOk()); outputData.setCode(outputContext.getOk());
outputData.setContent(outputContext.getCoreResponse().getString("text")); outputData.setContent(getContent(outputContext));
outputData.setUserInfo(outputContext.getUserInfo()); outputData.setUserInfo(outputContext.getUserInfo());
outputData.setDateTime(outputContext.getDateTime()); outputData.setDateTime(outputContext.getDateTime());
return outputData; return outputData;
} }
private String getContent(PartnerRunningFlowContext outputContext) {
StringBuilder str = new StringBuilder();
str.append(outputContext.getCoreResponse().getString("text")).append("\r\n")
.append("\r\n错误信息:\r\n")
.append(outputContext.getErrMsg().toString());
return str.toString();
}
@Override @Override
protected PartnerRunningFlowContext parseInputData(PartnerInputData inputData) { protected PartnerRunningFlowContext parseInputData(PartnerInputData inputData) {
PartnerRunningFlowContext context = new PartnerRunningFlowContext(); PartnerRunningFlowContext context = new PartnerRunningFlowContext();

View File

@@ -1,138 +0,0 @@
package work.slhaf.partner.runtime.session;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.api.agent.runtime.config.AgentConfigManager;
import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.api.chat.pojo.MetaMessage;
import work.slhaf.partner.api.common.entity.PersistableObject;
import work.slhaf.partner.common.config.PartnerAgentConfigManager;
import work.slhaf.partner.common.exception.ServiceLoadFailedException;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@EqualsAndHashCode(callSuper = true)
@Data
@Slf4j
public class SessionManager extends PersistableObject {
@Serial
private static final long serialVersionUID = 1L;
private static final String STORAGE_DIR = "./data/session/";
private static volatile SessionManager sessionManager;
private String id;
private HashMap<String /*startUserId*/, List<MetaMessage>> singleMetaMessageMap;
private String currentMemoryId;
private long lastUpdatedTime;
public static SessionManager getInstance() {
if (sessionManager == null) {
synchronized (SessionManager.class) {
if (sessionManager == null) {
String id = ((PartnerAgentConfigManager) AgentConfigManager.INSTANCE).getConfig().getAgentId();
Path filePath = Paths.get(STORAGE_DIR, id + ".session");
if (Files.exists(filePath)) {
sessionManager = deserialize(id);
if (sessionManager == null){
throw new ServiceLoadFailedException("SessionManager 加载失败");
}
} else {
sessionManager = new SessionManager();
sessionManager.setSingleMetaMessageMap(new HashMap<>());
sessionManager.id = id;
sessionManager.setShutdownHook();
sessionManager.lastUpdatedTime = 0;
}
}
}
}
return sessionManager;
}
private void setShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
sessionManager.serialize();
log.info("[SessionManager] SessionManager 已保存");
} catch (IOException e) {
log.error("[SessionManager] 保存 SessionManager 失败: ", e);
}
}));
}
public void addMetaMessage(String userId, MetaMessage metaMessage) {
log.debug("[SessionManager] 当前会话历史: {}", JSONObject.toJSONString(singleMetaMessageMap));
if (singleMetaMessageMap.containsKey(userId)) {
singleMetaMessageMap.get(userId).add(metaMessage);
} else {
singleMetaMessageMap.put(userId, new java.util.ArrayList<>());
singleMetaMessageMap.get(userId).add(metaMessage);
}
log.debug("[SessionManager] 会话历史更新: {}", JSONObject.toJSONString(singleMetaMessageMap));
}
public List<Message> unpackAndClear(String userId) {
List<Message> messages = new ArrayList<>();
for (MetaMessage metaMessage : singleMetaMessageMap.get(userId)) {
messages.add(metaMessage.getUserMessage());
messages.add(metaMessage.getAssistantMessage());
}
singleMetaMessageMap.remove(userId);
return messages;
}
public void refreshMemoryId() {
currentMemoryId = UUID.randomUUID().toString();
}
public void serialize() throws IOException {
//先写入到临时文件,如果正常写入,则覆盖正式文件;否则删除临时文件
Path filePath = getFilePath(this.id + "-temp");
Files.createDirectories(Path.of(STORAGE_DIR));
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()));
oos.writeObject(this);
oos.close();
Path path = getFilePath(this.id);
Files.move(filePath, path, StandardCopyOption.REPLACE_EXISTING);
log.info("[SessionManager] SessionManager 已保存到: {}", path);
} catch (IOException e) {
Files.delete(filePath);
log.error("[SessionManager] 序列化保存失败: {}", e.getMessage());
}
}
private static SessionManager deserialize(String id) {
Path filePath = getFilePath(id);
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath.toFile()))) {
SessionManager sessionManager = (SessionManager) ois.readObject();
log.info("[SessionManager] SessionManager 已从文件加载: {}", filePath);
return sessionManager;
}catch (IOException | ClassNotFoundException e) {
log.error("[SessionManager] 读取异常, 读取失败: ", e);
return null;
}
}
public void resetLastUpdatedTime() {
lastUpdatedTime = System.currentTimeMillis();
}
private static Path getFilePath(String id) {
return Paths.get(STORAGE_DIR, id + ".session");
}
}

View File

@@ -1,9 +1,8 @@
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import work.slhaf.partner.core.submodule.memory.MemoryCapability; import work.slhaf.partner.core.memory.MemoryCapability;
import work.slhaf.partner.core.submodule.memory.pojo.MemoryResult; import work.slhaf.partner.core.memory.pojo.MemoryResult;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.function.Function;
public class ReflectionTest { public class ReflectionTest {
@@ -21,9 +20,5 @@ public class ReflectionTest {
return null; return null;
}); });
memory.selectMemory("111"); memory.selectMemory("111");
Function<String, Integer> function = s -> {
return s.length();
};
} }
} }

View File

@@ -1,53 +1,48 @@
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test
import java.lang.String.join
import java.util.regex.Pattern
import java.util.ArrayList; class RegexTest {
import java.util.List; @Test
import java.util.regex.Matcher; fun regexTest() {
import java.util.regex.Pattern; val examples = arrayListOf(
"[小明(abc)] 我在开会] (te[]st)",
"[用户(昵)称(userId)] 你好[呀]",
"[测试账号(userId)] 这是一个(test(123))消息"
)
public class RegexTest { val pattern = Pattern.compile("\\[.*?\\(([^)]+)\\)\\]")
// @Test for (example in examples) {
public void regexTest(){ val matcher = pattern.matcher(example)
String[] examples = {
"[小明(abc)] 我在开会] (te[]st)",
"[用户(昵)称(userId)] 你好[呀]",
"[测试账号(userId)] 这是一个(test(123))消息"
};
Pattern pattern = Pattern.compile("\\[.*?\\(([^)]+)\\)\\]");
for (String example : examples) {
Matcher matcher = pattern.matcher(example);
if (matcher.find()) { if (matcher.find()) {
System.out.println("在 '" + example + "' 中找到 userId: " + matcher.group(1)); println("在 '$example' 中找到 userId: ${matcher.group(1)}")
System.out.println(); println()
} else { } else {
System.out.println("在 '" + example + "' 中未找到 userId"); println("在 '$example' 中未找到 userId")
} }
} }
} }
@Test @Test
public void topicPathFixTest(){ fun topicPathFixTest() {
String a = "xxxxx[awdohno][awdsjo]"; var a = "xxxxx[awdohno][awdsjo]"
a = fix(a); a = fix(a)
System.out.println(a); println(a)
} }
private String fix(String topicPath) { private fun fix(topicPath: String): String {
String[] parts = topicPath.split("->"); val parts = topicPath.split("->".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
List<String> cleanedParts = new ArrayList<>(); val cleanedParts: MutableList<String?> = ArrayList<String?>()
for (String part : parts) { for (part in parts) {
// 修正正则表达式,正确移除 [xxx] 部分 // 修正正则表达式,正确移除 [xxx] 部分
String cleaned = part.replaceAll("\\[[^\\]]*\\]", "").trim(); val cleaned = part.replace("\\[[^\\]]*\\]".toRegex(), "").trim { it <= ' ' }
if (!cleaned.isEmpty()) { // 忽略空字符串 if (!cleaned.isEmpty()) { // 忽略空字符串
cleanedParts.add(cleaned); cleanedParts.add(cleaned)
} }
} }
return String.join("->", cleanedParts); return join("->", cleanedParts)
} }
} }

View File

@@ -6,7 +6,7 @@ import work.slhaf.partner.api.chat.pojo.ChatResponse;
import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.api.chat.pojo.Message;
import work.slhaf.partner.common.util.ResourcesUtil; import work.slhaf.partner.common.util.ResourcesUtil;
import work.slhaf.partner.module.common.model.ModelConstant; import work.slhaf.partner.module.common.model.ModelConstant;
import work.slhaf.partner.module.modules.memory.selector.extractor.data.ExtractorInput; import work.slhaf.partner.module.modules.memory.selector.extractor.entity.ExtractorInput;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;

View File

@@ -0,0 +1,20 @@
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
launch {
delay(1000)
println(11)
}
launch {
delay(1000)
println(22)
}
launch {
delay(1000)
println(33)
}
launch {
}
}

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>Partner</artifactId>
<groupId>work.slhaf</groupId>
<version>0.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Partner-Test-Demo</artifactId>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer>
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -25,4 +25,49 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 添加 maven-shade-plugin 插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

87
pom.xml
View File

@@ -18,42 +18,79 @@
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>2.2.0</kotlin.version>
</properties> </properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build> <build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>kotlin-maven-plugin</artifactId>
<version>3.2.0</version> <version>${kotlin.version}</version>
<configuration>
<archive>
<manifest>
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 添加 maven-shade-plugin 插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <id>compile</id>
<phase>compile</phase>
<goals> <goals>
<goal>shade</goal> <goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals> </goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>work.slhaf.demo.AgentDemoApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution> </execution>
</executions> </executions>
<configuration>
<jvmTarget>${maven.compiler.target}</jvmTarget>
</configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>