From 5f0165fa3a20613f8bb214c1799d4c63137719fc Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Sun, 15 Feb 2026 21:26:17 +0800 Subject: [PATCH] refactor(Action): split ActionData into Action/ExecutableAction and unify scheduled action types --- .../partner/core/action/ActionCapability.java | 16 +-- .../slhaf/partner/core/action/ActionCore.java | 102 +++++++++--------- .../entity/{ActionData.kt => Action.kt} | 77 +++++++------ .../core/action/entity/PhaserRecord.java | 12 +-- .../action/dispatcher/ActionDispatcher.java | 18 ++-- .../dispatcher/executor/ActionExecutor.java | 48 ++++----- .../executor/entity/ActionExecutorInput.kt | 4 +- .../executor/entity/CorrectorInput.java | 4 +- .../dispatcher/scheduler/ActionScheduler.kt | 51 ++++----- .../action/interventor/ActionInterventor.java | 8 +- .../evaluator/InterventionEvaluator.java | 12 +-- .../evaluator/entity/EvaluatorInput.java | 6 +- .../recognizer/InterventionRecognizer.java | 26 ++--- .../recognizer/entity/RecognizerInput.java | 6 +- .../recognizer/entity/RecognizerResult.java | 6 +- .../modules/action/planner/ActionPlanner.java | 42 ++++---- .../planner/confirmer/ActionConfirmer.java | 16 +-- .../confirmer/entity/ConfirmerInput.java | 4 +- .../evaluator/entity/EvaluatorResult.java | 4 +- .../executor/ActionExecutorTest.java | 38 +++---- .../executor/ActionSchedulerTest.kt | 55 +++++----- 21 files changed, 283 insertions(+), 272 deletions(-) rename Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/{ActionData.kt => Action.kt} (80%) diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java index 1f99bfe0..a22a1758 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCapability.java @@ -3,7 +3,7 @@ package work.slhaf.partner.core.action; import lombok.NonNull; import org.jetbrains.annotations.Nullable; import work.slhaf.partner.api.agent.factory.capability.annotation.Capability; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaActionInfo; import work.slhaf.partner.core.action.entity.PhaserRecord; @@ -20,15 +20,15 @@ import java.util.concurrent.Phaser; @Capability(value = "action") public interface ActionCapability { - void putAction(@NonNull ActionData actionData); + void putAction(@NonNull ExecutableAction executableAction); - Set listActions(@Nullable ActionData.ActionStatus actionStatus, @Nullable String source); + Set listActions(@Nullable ExecutableAction.Status status, @Nullable String source); - List popPendingAction(String userId); + List popPendingAction(String userId); - List listPendingAction(String userId); + List listPendingAction(String userId); - void putPendingActions(String userId, ActionData actionData); + void putPendingActions(String userId, ExecutableAction executableAction); List selectTendencyCache(String input); @@ -36,7 +36,7 @@ public interface ActionCapability { ExecutorService getExecutor(ActionCore.ExecutorType type); - PhaserRecord putPhaserRecord(Phaser phaser, ActionData actionData); + PhaserRecord putPhaserRecord(Phaser phaser, ExecutableAction executableAction); void removePhaserRecord(Phaser phaser); @@ -54,6 +54,6 @@ public interface ActionCapability { RunnerClient runnerClient(); - void handleInterventions(List interventions, ActionData data); + void handleInterventions(List interventions, ExecutableAction data); } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java index 140238f7..7e0d6a71 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/ActionCore.java @@ -8,7 +8,7 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.core.PartnerCore; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaActionInfo; import work.slhaf.partner.core.action.entity.PhaserRecord; @@ -37,12 +37,12 @@ public class ActionCore extends PartnerCore { /** * 持久行动池 */ - private CopyOnWriteArraySet actionPool = new CopyOnWriteArraySet<>(); + private CopyOnWriteArraySet actionPool = new CopyOnWriteArraySet<>(); /** * 待确认任务,以userId区分不同用户,因为需要跨请求确认 */ - private HashMap> pendingActions = new HashMap<>(); + private HashMap> pendingActions = new HashMap<>(); /** * 语义缓存与行为倾向映射 @@ -71,45 +71,45 @@ public class ActionCore extends PartnerCore { private void setupShutdownHook() { // 将执行中的行动状态置为失败 - val executingActionSet = listActions(ActionData.ActionStatus.EXECUTING, null); - for (ActionData actionData : executingActionSet) { - actionData.setStatus(ActionData.ActionStatus.FAILED); - actionData.setResult("由于系统中断而失败"); + val executingActionSet = listActions(ExecutableAction.Status.EXECUTING, null); + for (ExecutableAction executableAction : executingActionSet) { + executableAction.setStatus(ExecutableAction.Status.FAILED); + executableAction.setResult("由于系统中断而失败"); } } @CapabilityMethod - public void putAction(@NonNull ActionData actionData) { - actionPool.removeIf(data -> data.getUuid().equals(actionData.getUuid())); // 用来应对 ScheduledActionData 的重新排列 - actionPool.add(actionData); + public void putAction(@NonNull ExecutableAction executableAction) { + actionPool.removeIf(data -> data.getUuid().equals(executableAction.getUuid())); // 用来应对 ScheduledActionData 的重新排列 + actionPool.add(executableAction); } @CapabilityMethod - public Set listActions(@Nullable ActionData.ActionStatus actionStatus, @Nullable String source) { + public Set listActions(@Nullable ExecutableAction.Status status, @Nullable String source) { return actionPool.stream() - .filter(actionData -> actionStatus == null || actionData.getStatus().equals(actionStatus)) + .filter(actionData -> status == null || actionData.getStatus().equals(status)) .filter(actionData -> source == null || actionData.getSource().equals(source)) .collect(Collectors.toSet()); } @CapabilityMethod - public synchronized void putPendingActions(String userId, ActionData actionData) { + public synchronized void putPendingActions(String userId, ExecutableAction executableAction) { pendingActions.computeIfAbsent(userId, k -> { - List temp = new ArrayList<>(); - temp.add(actionData); + List temp = new ArrayList<>(); + temp.add(executableAction); return temp; }); } @CapabilityMethod - public synchronized List popPendingAction(String userId) { - List infos = pendingActions.get(userId); + public synchronized List popPendingAction(String userId) { + List infos = pendingActions.get(userId); pendingActions.remove(userId); return infos; } @CapabilityMethod - public List listPendingAction(String userId) { + public List listPendingAction(String userId) { return pendingActions.get(userId); } @@ -180,8 +180,8 @@ public class ActionCore extends PartnerCore { } @CapabilityMethod - public synchronized PhaserRecord putPhaserRecord(Phaser phaser, ActionData actionData) { - PhaserRecord record = new PhaserRecord(phaser, actionData); + public synchronized PhaserRecord putPhaserRecord(Phaser phaser, ExecutableAction executableAction) { + PhaserRecord record = new PhaserRecord(phaser, executableAction); phaserRecords.add(record); return record; } @@ -203,7 +203,7 @@ public class ActionCore extends PartnerCore { @CapabilityMethod public PhaserRecord getPhaserRecord(String tendency, String source) { for (PhaserRecord record : phaserRecords) { - ActionData data = record.actionData(); + ExecutableAction data = record.executableAction(); if (data.getTendency().equals(tendency) && data.getSource().equals(source)) { return record; } @@ -255,19 +255,19 @@ public class ActionCore extends PartnerCore { } @CapabilityMethod - public void handleInterventions(List interventions, ActionData actionData) { + public void handleInterventions(List interventions, ExecutableAction executableAction) { // 加载数据 - if (actionData == null) { + if (executableAction == null) { return; } // 加锁确保同步 - synchronized (actionData.getStatus()) { - applyInterventions(interventions, actionData); + synchronized (executableAction.getStatus()) { + applyInterventions(interventions, executableAction); } } - private void applyInterventions(List interventions, ActionData actionData) { + private void applyInterventions(List interventions, ExecutableAction executableAction) { boolean rebuildCleanTag = false; interventions.sort(Comparator.comparingInt(MetaIntervention::getOrder)); @@ -279,16 +279,16 @@ public class ActionCore extends PartnerCore { .toList(); switch (intervention.getType()) { - case InterventionType.APPEND -> handleAppend(actionData, intervention.getOrder(), actions); - case InterventionType.INSERT -> handleInsert(actionData, intervention.getOrder(), actions); - case InterventionType.DELETE -> handleDelete(actionData, intervention.getOrder(), actions); - case InterventionType.CANCEL -> handleCancel(actionData); + case InterventionType.APPEND -> handleAppend(executableAction, intervention.getOrder(), actions); + case InterventionType.INSERT -> handleInsert(executableAction, intervention.getOrder(), actions); + case InterventionType.DELETE -> handleDelete(executableAction, intervention.getOrder(), actions); + case InterventionType.CANCEL -> handleCancel(executableAction); case InterventionType.REBUILD -> { if (!rebuildCleanTag) { - cleanActionData(actionData); + cleanActionData(executableAction); rebuildCleanTag = true; } - handleRebuild(actionData, intervention.getOrder(), actions); + handleRebuild(executableAction, intervention.getOrder(), actions); } } } @@ -298,28 +298,28 @@ public class ActionCore extends PartnerCore { /** * 在未进入执行阶段的行动单元组新增新的行动 */ - private void handleAppend(ActionData actionData, int order, List actions) { - if (order <= actionData.getExecutingStage()) + private void handleAppend(ExecutableAction executableAction, int order, List actions) { + if (order <= executableAction.getExecutingStage()) return; - actionData.getActionChain().put(order, actions); + executableAction.getActionChain().put(order, actions); } /** * 在未进入执行阶段和正处于行动阶段的行动单元组插入新的行动 */ - private void handleInsert(ActionData actionData, int order, List actions) { - if (order < actionData.getExecutingStage()) + private void handleInsert(ExecutableAction executableAction, int order, List actions) { + if (order < executableAction.getExecutingStage()) return; - actionData.getActionChain().computeIfAbsent(order, k -> new ArrayList<>()).addAll(actions); + executableAction.getActionChain().computeIfAbsent(order, k -> new ArrayList<>()).addAll(actions); } - private void handleDelete(ActionData actionData, int order, List actions) { - if (order <= actionData.getExecutingStage()) + private void handleDelete(ExecutableAction executableAction, int order, List actions) { + if (order <= executableAction.getExecutingStage()) return; - Map> actionChain = actionData.getActionChain(); + Map> actionChain = executableAction.getActionChain(); if (actionChain.containsKey(order)) { actionChain.get(order).removeAll(actions); if (actionChain.get(order).isEmpty()) { @@ -328,21 +328,21 @@ public class ActionCore extends PartnerCore { } } - private void handleCancel(ActionData actionData) { - actionData.setStatus(ActionData.ActionStatus.FAILED); - actionData.setResult("行动取消"); + private void handleCancel(ExecutableAction executableAction) { + executableAction.setStatus(ExecutableAction.Status.FAILED); + executableAction.setResult("行动取消"); } - private void handleRebuild(ActionData actionData, int order, List actions) { - Map> actionChain = actionData.getActionChain(); + private void handleRebuild(ExecutableAction executableAction, int order, List actions) { + Map> actionChain = executableAction.getActionChain(); actionChain.put(order, actions); } - private void cleanActionData(ActionData actionData) { - actionData.getActionChain().clear(); - actionData.setExecutingStage(0); - actionData.setStatus(ActionData.ActionStatus.PREPARE); - actionData.getHistory().clear(); + private void cleanActionData(ExecutableAction executableAction) { + executableAction.getActionChain().clear(); + executableAction.setExecutingStage(0); + executableAction.setStatus(ExecutableAction.Status.PREPARE); + executableAction.getHistory().clear(); } /** diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.kt b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/Action.kt similarity index 80% rename from Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.kt rename to Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/Action.kt index 9aededd8..1304a51e 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/ActionData.kt +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/Action.kt @@ -4,15 +4,44 @@ import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.Histo import java.time.ZonedDateTime import java.util.* -/** - * 行动模块传递的行动数据,包含行动uuid、倾向、状态、行动链、结果、发起原因、行动描述等信息。 - */ -sealed class ActionData { +sealed class Action { /** * 行动ID */ val uuid: String = UUID.randomUUID().toString() + /** + * 行动来源 + */ + abstract val source: String + + /** + * 行动原因 + */ + abstract val reason: String + + /** + * 行动描述 + */ + abstract val description: String + +} + +sealed interface Scheduled { + + val scheduleType: ScheduleType + val scheduleContent: String + + enum class ScheduleType { + CYCLE, + ONCE + } +} + +/** + * 行动模块传递的行动数据,包含行动uuid、倾向、状态、行动链、结果、发起原因、行动描述等信息。 + */ +sealed class ExecutableAction : Action() { /** * 行动倾向 */ @@ -21,7 +50,7 @@ sealed class ActionData { /** * 行动状态 */ - var status: ActionStatus = ActionStatus.PREPARE + var status: Status = Status.PREPARE /** * 行动链 @@ -45,22 +74,7 @@ sealed class ActionData { */ val additionalContext: MutableMap> = mutableMapOf() - /** - * 行动原因 - */ - abstract val reason: String - - /** - * 行动描述 - */ - abstract val description: String - - /** - * 行动来源 - */ - abstract val source: String - - enum class ActionStatus { + enum class Status { /** * 执行成功 */ @@ -89,17 +103,17 @@ sealed class ActionData { } /** - * 计划行动数据类,继承自{@link ActionData},扩展了属性{@link ScheduledActionData#type}和{@link ScheduledActionData#scheduleContent},用于标识计划类型(单次还是周期性任务)和计划内容 + * 计划行动数据类,继承自[Action],扩展了[Scheduled]相关调度属性,用于标识计划类型(单次还是周期性任务)和计划内容 */ -data class ScheduledActionData( +data class ScheduledExecutableAction( override val tendency: String, override val actionChain: MutableMap>, override val reason: String, override val description: String, override val source: String, - val scheduleType: ScheduleType, - val scheduleContent: String, -) : ActionData() { + override val scheduleType: Scheduled.ScheduleType, + override val scheduleContent: String +) : ExecutableAction(), Scheduled { val scheduleHistories = ArrayList() @@ -116,12 +130,7 @@ data class ScheduledActionData( } } - status = ActionStatus.PREPARE - } - - enum class ScheduleType { - CYCLE, - ONCE + status = Status.PREPARE } data class ScheduleHistory( @@ -134,10 +143,10 @@ data class ScheduledActionData( /** * 即时行动数据类 */ -data class ImmediateActionData( +data class ImmediateExecutableAction( override val tendency: String, override val actionChain: MutableMap>, override val reason: String, override val description: String, override val source: String, -) : ActionData() +) : ExecutableAction() diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java index c0c85289..6d12f058 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java @@ -1,13 +1,13 @@ package work.slhaf.partner.core.action.entity; -import work.slhaf.partner.core.action.entity.ActionData.ActionStatus; +import work.slhaf.partner.core.action.entity.ExecutableAction.Status; import java.util.concurrent.Phaser; -public record PhaserRecord(Phaser phaser, ActionData actionData) { +public record PhaserRecord(Phaser phaser, ExecutableAction executableAction) { public void fail() { - actionData.setStatus(ActionStatus.FAILED); + executableAction.setStatus(Status.FAILED); } /** @@ -15,8 +15,8 @@ public record PhaserRecord(Phaser phaser, ActionData actionData) { * 同时循环检查进行阻塞 */ public void interrupt() { - actionData.setStatus(ActionStatus.INTERRUPTED); - while (actionData().getStatus() == ActionStatus.INTERRUPTED) { + executableAction.setStatus(Status.INTERRUPTED); + while (executableAction().getStatus() == Status.INTERRUPTED) { try { Thread.sleep(500); } catch (InterruptedException ignored) { @@ -28,6 +28,6 @@ public record PhaserRecord(Phaser phaser, ActionData actionData) { * 将状态重新设置为 EXECUTING ,恢复 interrupt 阻塞状态 */ public void complete() { - actionData().setStatus(ActionStatus.EXECUTING); + executableAction().setStatus(Status.EXECUTING); } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/ActionDispatcher.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/ActionDispatcher.java index 40b5b240..ad20698f 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/ActionDispatcher.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/ActionDispatcher.java @@ -7,9 +7,9 @@ import work.slhaf.partner.api.agent.factory.module.annotation.Init; import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; -import work.slhaf.partner.core.action.entity.ActionData; -import work.slhaf.partner.core.action.entity.ImmediateActionData; -import work.slhaf.partner.core.action.entity.ScheduledActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; +import work.slhaf.partner.core.action.entity.ImmediateExecutableAction; +import work.slhaf.partner.core.action.entity.ScheduledExecutableAction; import work.slhaf.partner.module.common.module.PostRunningModule; import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor; import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput; @@ -46,14 +46,14 @@ public class ActionDispatcher extends PostRunningModule { // action,理想做法是将执行工具做成执行链的形式,模型的自对话流程、是否通知用户都做成与普通工具同等的通用可选能力,避免绑定固定流程 executor.execute(() -> { String userId = context.getUserId(); - val preparedActions = actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId); + val preparedActions = actionCapability.listActions(ExecutableAction.Status.PREPARE, userId); // 分类成PLANNING和IMMEDIATE两类 - Set scheduledActions = new HashSet<>(); - Set immediateActions = new HashSet<>(); - for (ActionData preparedAction : preparedActions) { - if (preparedAction instanceof ScheduledActionData actionInfo) { + Set scheduledActions = new HashSet<>(); + Set immediateActions = new HashSet<>(); + for (ExecutableAction preparedAction : preparedActions) { + if (preparedAction instanceof ScheduledExecutableAction actionInfo) { scheduledActions.add(actionInfo); - } else if (preparedAction instanceof ImmediateActionData actionInfo) { + } else if (preparedAction instanceof ImmediateExecutableAction actionInfo) { immediateActions.add(actionInfo); } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java index f3cbd9b9..0fe9fe96 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java @@ -10,7 +10,7 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunn import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; import work.slhaf.partner.core.action.entity.*; -import work.slhaf.partner.core.action.entity.ActionData.ActionStatus; +import work.slhaf.partner.core.action.entity.ExecutableAction.Status; import work.slhaf.partner.core.action.runner.RunnerClient; import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.memory.MemoryCapability; @@ -69,22 +69,22 @@ public class ActionExecutor extends AgentRunningSubModule { - val source = actionData.getSource(); - if (actionData.getStatus() != ActionStatus.PREPARE) { + val source = executableAction.getSource(); + if (executableAction.getStatus() != Status.PREPARE) { return; } - val actionChain = actionData.getActionChain(); + val actionChain = executableAction.getActionChain(); if (actionChain.isEmpty()) { - actionData.setStatus(ActionStatus.FAILED); - actionData.setResult("行动链为空"); + executableAction.setStatus(Status.FAILED); + executableAction.setResult("行动链为空"); return; } // 注册执行中行动 val phaser = new Phaser(); - val phaserRecord = actionCapability.putPhaserRecord(phaser, actionData); - actionData.setStatus(ActionStatus.EXECUTING); + val phaserRecord = actionCapability.putPhaserRecord(phaser, executableAction); + executableAction.setStatus(Status.EXECUTING); // 开始执行 val stageCursor = new Object() { @@ -120,13 +120,13 @@ public class ActionExecutor extends AgentRunningSubModule(actionChain.keySet()); orderList.sort(Integer::compareTo); - actionData.setExecutingStage(orderList.get(stageCount)); + executableAction.setExecutingStage(orderList.get(stageCount)); } }; stageCursor.init(); do { - val metaActions = actionChain.get(actionData.getExecutingStage()); + val metaActions = actionChain.get(executableAction.getExecutingStage()); val listeningRecord = executeAndListening(metaActions, phaserRecord, source); phaser.awaitAdvance(listeningRecord.phase()); @@ -144,9 +144,9 @@ public class ActionExecutor extends AgentRunningSubModule) +data class ActionExecutorInput(val actions: Set) diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java index 1c2c9af8..80e1fdb2 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/CorrectorInput.java @@ -3,7 +3,7 @@ package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; import lombok.Builder; import lombok.Data; import work.slhaf.partner.api.chat.pojo.Message; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; import java.util.List; @@ -17,7 +17,7 @@ public class CorrectorInput { private String description; private List history; - private ActionData.ActionStatus status; + private ExecutableAction.Status status; private List recentMessages; private List activatedSlices; diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt index fc192696..ef38f697 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/scheduler/ActionScheduler.kt @@ -17,8 +17,9 @@ 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.runtime.interaction.flow.abstracts.AgentRunningSubModule import work.slhaf.partner.core.action.ActionCapability -import work.slhaf.partner.core.action.entity.ActionData -import work.slhaf.partner.core.action.entity.ScheduledActionData +import work.slhaf.partner.core.action.entity.ExecutableAction +import work.slhaf.partner.core.action.entity.Scheduled +import work.slhaf.partner.core.action.entity.ScheduledExecutableAction import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput import java.io.Closeable @@ -29,7 +30,7 @@ import java.util.stream.Collectors import kotlin.jvm.optionals.getOrNull @AgentSubModule -class ActionScheduler : AgentRunningSubModule, Void>() { +class ActionScheduler : AgentRunningSubModule, Void>() { @InjectCapability private lateinit var actionCapability: ActionCapability @@ -48,15 +49,15 @@ class ActionScheduler : AgentRunningSubModule, Void>() @Init fun init() { - val listScheduledActions: () -> Set = { + val listScheduledActions: () -> Set = { actionCapability.listActions(null, null) .stream() - .filter { it is ScheduledActionData } - .map { it as ScheduledActionData } + .filter { it is ScheduledExecutableAction } + .map { it as ScheduledExecutableAction } .collect(Collectors.toSet()) } - val onTrigger: (Set) -> Unit = { actionExecutor.execute(ActionExecutorInput(it)) } + val onTrigger: (Set) -> Unit = { actionExecutor.execute(ActionExecutorInput(it)) } timeWheel = TimeWheel(listScheduledActions, onTrigger) @@ -71,7 +72,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() } // TODO 如果要将 TimeWheel 作为 Agent 内部的循环周期,那么不依赖 Action 链路的内容,将不适合参与到 ActionExecutor,因此需要将 ActionData 的触发类型进行分类:SILENT TRIGGER(仅限更新 ActionData 内部状态,通过属性 copy 完成,不开放过多权限,防止序列化失败)、EXECUTOR、AGENT TURN。考虑将时间轮下放至 ActionCapability,作为底层行动语义的一部分 - override fun execute(scheduledActionDataSet: Set?): Void? { + override fun execute(scheduledActionDataSet: Set?): Void? { schedulerScope.launch { scheduledActionDataSet?.run { for (scheduledActionData in scheduledActionDataSet) { @@ -85,12 +86,12 @@ class ActionScheduler : AgentRunningSubModule, Void>() } private class TimeWheel( - val listScheduledActions: () -> Set, - val onTrigger: (toTrigger: Set) -> Unit + val listScheduledActions: () -> Set, + val onTrigger: (toTrigger: Set) -> Unit ) : Closeable { - private val actionsGroupByHour = Array>(24) { mutableSetOf() } - private val wheel = Array>(60 * 60) { mutableSetOf() } + private val actionsGroupByHour = Array>(24) { mutableSetOf() } + private val wheel = Array>(60 * 60) { mutableSetOf() } private var recordHour: Int = -1 private var recordDay: Int = -1 private val state = MutableStateFlow(WheelState.SLEEPING) @@ -109,8 +110,8 @@ class ActionScheduler : AgentRunningSubModule, Void>() launchWheel() } - suspend fun schedule(actionData: ScheduledActionData) { - if (actionData.status != ActionData.ActionStatus.PREPARE) { + suspend fun schedule(actionData: ScheduledExecutableAction) { + if (actionData.status != ExecutableAction.Status.PREPARE) { return } @@ -141,9 +142,9 @@ class ActionScheduler : AgentRunningSubModule, Void>() private fun launchWheel() { - fun collectToTrigger(tick: Int, previousTick: Int, triggerHour: Int): Set? { + fun collectToTrigger(tick: Int, previousTick: Int, triggerHour: Int): Set? { if (tick > previousTick) { - val toTrigger = mutableSetOf() + val toTrigger = mutableSetOf() for (i in previousTick..tick) { val bucket = wheel[i] if (bucket.isNotEmpty()) { @@ -178,7 +179,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() nextTickNanos += step.toLong() * 1_000_000_000L var shouldBreak = false - var toTrigger: Set? = null + var toTrigger: Set? = null checkThenExecute(false) { if (it.hour != launchingHour) { @@ -265,9 +266,9 @@ class ActionScheduler : AgentRunningSubModule, Void>() suspend fun checkThenExecute(finallyToExecute: Boolean = true, then: (currentTime: ZonedDateTime) -> Unit) = wheelActionsLock.withLock { fun loadActions( - source: Set, + source: Set, now: ZonedDateTime, - load: (latestExecutingTime: ZonedDateTime, actionData: ScheduledActionData) -> Unit, + load: (latestExecutingTime: ZonedDateTime, actionData: ScheduledExecutableAction) -> Unit, repair: () -> Unit ) { val runLoading = { @@ -291,7 +292,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() } fun loadHourActions(currentTime: ZonedDateTime) { - val load: (ZonedDateTime, ScheduledActionData) -> Unit = { latestExecutionTime, actionData -> + val load: (ZonedDateTime, ScheduledExecutableAction) -> Unit = { latestExecutionTime, actionData -> val secondsTime = latestExecutionTime.minute * 60 + latestExecutionTime.second wheel[secondsTime].add(actionData) log.debug("Action loaded to hour: {}", actionData) @@ -307,7 +308,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() } fun loadDayActions(currentTime: ZonedDateTime) { - val load: (ZonedDateTime, ScheduledActionData) -> Unit = { latestExecutingTime, actionData -> + val load: (ZonedDateTime, ScheduledExecutableAction) -> Unit = { latestExecutingTime, actionData -> actionsGroupByHour[latestExecutingTime.hour].add(actionData) log.debug("Action loaded to day: {}", actionData) } @@ -347,12 +348,12 @@ class ActionScheduler : AgentRunningSubModule, Void>() } private fun parseToZonedDateTime( - scheduleType: ScheduledActionData.ScheduleType, + scheduleType: Scheduled.ScheduleType, scheduleContent: String, now: ZonedDateTime ): ZonedDateTime? { return when (scheduleType) { - ScheduledActionData.ScheduleType.CYCLE + Scheduled.ScheduleType.CYCLE -> { val cron = try { cronParser.parse(scheduleContent).validate() @@ -363,7 +364,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() executionTime.nextExecution(now).getOrNull() } - ScheduledActionData.ScheduleType.ONCE -> { + Scheduled.ScheduleType.ONCE -> { val executionTime = try { ZonedDateTime.parse(scheduleContent) } catch (_: Exception) { @@ -379,7 +380,7 @@ class ActionScheduler : AgentRunningSubModule, Void>() } - private fun logFailedStatus(actionData: ScheduledActionData) { + private fun logFailedStatus(actionData: ScheduledExecutableAction) { log.warn( "行动未加载,uuid: {}, source: {}, tendency: {}, scheduleContent: {}", actionData.uuid, diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java index f81f1e88..9d5d45cd 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/ActionInterventor.java @@ -9,7 +9,7 @@ import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.action.entity.PhaserRecord; import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.memory.MemoryCapability; @@ -96,7 +96,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel } - private void handleInterventions(List interventionDataList, Map interventionDataMap) { + private void handleInterventions(List interventionDataList, Map interventionDataMap) { val executor = actionCapability.getExecutor(ActionCore.ExecutorType.PLATFORM); executor.execute(() -> { for (EvaluatedInterventionData interventionData : interventionDataList) { @@ -175,8 +175,8 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel recognizerInput.setUserDialogMapStr(memoryCapability.getUserDialogMapStr(userId)); // 参考的对话列表大小或需调整 recognizerInput.setRecentMessages(cognationCapability.getChatMessages()); - recognizerInput.setExecutingActions(actionCapability.listPhaserRecords().stream().map(PhaserRecord::actionData).toList()); - recognizerInput.setPreparedActions(actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId).stream().toList()); + recognizerInput.setExecutingActions(actionCapability.listPhaserRecords().stream().map(PhaserRecord::executableAction).toList()); + recognizerInput.setPreparedActions(actionCapability.listActions(ExecutableAction.Status.PREPARE, userId).stream().toList()); return recognizerInput; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java index f0675e9f..85adcc40 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/InterventionEvaluator.java @@ -10,7 +10,7 @@ import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore.ExecutorType; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorInput; import work.slhaf.partner.module.modules.action.interventor.evaluator.entity.EvaluatorResult; @@ -36,8 +36,8 @@ public class InterventionEvaluator extends AgentRunningSubModule executingInterventions = input.getExecutingInterventions(); - Map preparedInterventions = input.getPreparedInterventions(); + Map executingInterventions = input.getExecutingInterventions(); + Map preparedInterventions = input.getPreparedInterventions(); CountDownLatch latch = new CountDownLatch(executingInterventions.size() + preparedInterventions.size()); // 创建结果容器 @@ -58,7 +58,7 @@ public class InterventionEvaluator extends AgentRunningSubModule evaluatedDataList, Map interventionMap, EvaluatorInput input, ExecutorService executor, CountDownLatch latch) { + private void evaluateIntervention(List evaluatedDataList, Map interventionMap, EvaluatorInput input, ExecutorService executor, CountDownLatch latch) { interventionMap.forEach((tendency, actionData) -> executor.execute(() -> { try { String prompt = buildPrompt(input.getRecentMessages(), input.getActivatedSlices(), actionData, tendency); @@ -78,12 +78,12 @@ public class InterventionEvaluator extends AgentRunningSubModule recentMessages, List activatedSlices, - ActionData actionData, String tendency) { + ExecutableAction executableAction, String tendency) { JSONObject json = new JSONObject(); json.put("干预倾向", tendency); json.putArray("近期对话").addAll(recentMessages); json.putArray("参考记忆").addAll(activatedSlices); - json.put("将干预的行动", JSONObject.toJSONString(actionData)); + json.put("将干预的行动", JSONObject.toJSONString(executableAction)); return json.toJSONString(); } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java index d25d8729..379e5a67 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/evaluator/entity/EvaluatorInput.java @@ -2,7 +2,7 @@ package work.slhaf.partner.module.modules.action.interventor.evaluator.entity; import lombok.Data; import work.slhaf.partner.api.chat.pojo.Message; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.core.memory.pojo.EvaluatedSlice; import java.util.List; @@ -10,8 +10,8 @@ import java.util.Map; @Data public class EvaluatorInput { - private Map executingInterventions; - private Map preparedInterventions; + private Map executingInterventions; + private Map preparedInterventions; private List activatedSlices; private List recentMessages; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java index b809f35d..dfb023fb 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/InterventionRecognizer.java @@ -9,7 +9,7 @@ import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunn import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.MetaRecognizerResult; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerInput; import work.slhaf.partner.module.modules.action.interventor.recognizer.entity.RecognizerResult; @@ -30,14 +30,14 @@ public class InterventionRecognizer extends AgentRunningSubModule executingActions = input.getExecutingActions(); - List preparedActions = input.getPreparedActions(); + List executingActions = input.getExecutingActions(); + List preparedActions = input.getPreparedActions(); CountDownLatch countDownLatch = new CountDownLatch(executingActions.size() + preparedActions.size()); // 创建结果容器 RecognizerResult recognizerResult = new RecognizerResult(); - Map executingInterventions = recognizerResult.getExecutingInterventions(); - Map preparedInterventions = recognizerResult.getPreparedInterventions(); + Map executingInterventions = recognizerResult.getExecutingInterventions(); + Map preparedInterventions = recognizerResult.getPreparedInterventions(); // 执行识别操作 recognizeIntervention(executingInterventions, executingActions, executor, input, countDownLatch); @@ -51,8 +51,8 @@ public class InterventionRecognizer extends AgentRunningSubModule interventionsMap, List actions, ExecutorService executor, RecognizerInput input, CountDownLatch latch) { - for (ActionData data : actions) { + private void recognizeIntervention(Map interventionsMap, List actions, ExecutorService executor, RecognizerInput input, CountDownLatch latch) { + for (ExecutableAction data : actions) { executor.execute(() -> { try { String prompt = buildPrompt(data, input); @@ -72,15 +72,15 @@ public class InterventionRecognizer extends AgentRunningSubModule executingActions; - private List preparedActions; + private List executingActions; + private List preparedActions; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java index e05511ec..adfcad04 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/interventor/recognizer/entity/RecognizerResult.java @@ -1,7 +1,7 @@ package work.slhaf.partner.module.modules.action.interventor.recognizer.entity; import lombok.Data; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import java.util.HashMap; import java.util.Map; @@ -17,7 +17,7 @@ public class RecognizerResult { *
* value: 干预倾向将作用的行动数据 */ - private Map executingInterventions = new HashMap<>(); + private Map executingInterventions = new HashMap<>(); /** *

将被干预的‘等待中行动’

@@ -25,5 +25,5 @@ public class RecognizerResult { *
* value: 干预倾向将作用的行动数据 */ - private Map preparedInterventions = new HashMap<>(); + private Map preparedInterventions = new HashMap<>(); } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java index 4456406a..3e89a137 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/ActionPlanner.java @@ -143,21 +143,21 @@ public class ActionPlanner extends PreRunningModule { if (uuids == null) { return; } - List pendingActions = actionCapability.popPendingAction(context.getUserId()); - for (ActionData actionData : pendingActions) { - if (uuids.contains(actionData.getUuid())) { - actionCapability.putAction(actionData); + List pendingActions = actionCapability.popPendingAction(context.getUserId()); + for (ExecutableAction executableAction : pendingActions) { + if (uuids.contains(executableAction.getUuid())) { + actionCapability.putAction(executableAction); } } } private void putActionData(List evaluatorResults, PartnerRunningFlowContext context) { for (EvaluatorResult evaluatorResult : evaluatorResults) { - ActionData actionData = assemblyHelper.buildActionData(evaluatorResult, context.getUserId()); + ExecutableAction executableAction = assemblyHelper.buildActionData(evaluatorResult, context.getUserId()); if (evaluatorResult.isNeedConfirm()) { - actionCapability.putPendingActions(context.getUserId(), actionData); + actionCapability.putPendingActions(context.getUserId(), executableAction); } else { - actionCapability.putAction(actionData); + actionCapability.putAction(executableAction); } } } @@ -172,18 +172,18 @@ public class ActionPlanner extends PreRunningModule { } private void setupPendingActions(HashMap map, String userId) { - List actionData = actionCapability.listPendingAction(userId); - if (actionData == null || actionData.isEmpty()) { + List executableActionData = actionCapability.listPendingAction(userId); + if (executableActionData == null || executableActionData.isEmpty()) { map.put("[待确认行动] <等待用户确认的行动信息>", "无待确认行动"); return; } - for (int i = 0; i < actionData.size(); i++) { - map.put("[待确认行动 " + (i + 1) + " ] <等待用户确认的行动信息>", generateActionStr(actionData.get(i))); + for (int i = 0; i < executableActionData.size(); i++) { + map.put("[待确认行动 " + (i + 1) + " ] <等待用户确认的行动信息>", generateActionStr(executableActionData.get(i))); } } private void setupPreparedActions(HashMap map, String userId) { - val preparedActions = actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId).stream().toList(); + val preparedActions = actionCapability.listActions(ExecutableAction.Status.PREPARE, userId).stream().toList(); if (preparedActions.isEmpty()) { map.put("[预备行动] <预备执行或放入计划池的行动信息>", "无预备行动"); return; @@ -193,10 +193,10 @@ public class ActionPlanner extends PreRunningModule { } } - private String generateActionStr(ActionData actionData) { - return "<行动倾向>" + " : " + actionData.getTendency() + - "<行动原因>" + " : " + actionData.getReason() + - "<工具描述>" + " : " + actionData.getDescription(); + private String generateActionStr(ExecutableAction executableAction) { + return "<行动倾向>" + " : " + executableAction.getTendency() + + "<行动原因>" + " : " + executableAction.getReason() + + "<工具描述>" + " : " + executableAction.getDescription(); } @Override @@ -231,10 +231,10 @@ public class ActionPlanner extends PreRunningModule { return input; } - private ActionData buildActionData(EvaluatorResult evaluatorResult, String userId) { + private ExecutableAction buildActionData(EvaluatorResult evaluatorResult, String userId) { Map> actionChain = getActionChain(evaluatorResult); return switch (evaluatorResult.getType()) { - case PLANNING -> new ScheduledActionData( + case PLANNING -> new ScheduledExecutableAction( evaluatorResult.getTendency(), actionChain, evaluatorResult.getReason(), @@ -243,7 +243,7 @@ public class ActionPlanner extends PreRunningModule { evaluatorResult.getScheduleType(), evaluatorResult.getScheduleContent() ); - case IMMEDIATE -> new ImmediateActionData( + case IMMEDIATE -> new ImmediateExecutableAction( evaluatorResult.getTendency(), actionChain, evaluatorResult.getReason(), @@ -332,8 +332,8 @@ public class ActionPlanner extends PreRunningModule { private ConfirmerInput buildConfirmerInput(PartnerRunningFlowContext context) { ConfirmerInput confirmerInput = new ConfirmerInput(); confirmerInput.setInput(context.getInput()); - List pendingActions = actionCapability.listPendingAction(context.getUserId()); - confirmerInput.setActionData(pendingActions); + List pendingActions = actionCapability.listPendingAction(context.getUserId()); + confirmerInput.setExecutableActionData(pendingActions); return confirmerInput; } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java index 693cef18..931f3ed7 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/ActionConfirmer.java @@ -11,7 +11,7 @@ import work.slhaf.partner.api.chat.pojo.ChatResponse; import work.slhaf.partner.api.chat.pojo.Message; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerInput; import work.slhaf.partner.module.modules.action.planner.confirmer.entity.ConfirmerResult; @@ -30,23 +30,23 @@ public class ActionConfirmer extends AgentRunningSubModule actionDataList = data.getActionData(); + List executableActionList = data.getExecutableActionData(); ExecutorService executor = actionCapability.getExecutor(ActionCore.ExecutorType.VIRTUAL); - CountDownLatch latch = new CountDownLatch(actionDataList.size()); + CountDownLatch latch = new CountDownLatch(executableActionList.size()); ConfirmerResult result = new ConfirmerResult(); List uuids = result.getUuids(); - for (ActionData actionData : actionDataList) { + for (ExecutableAction executableAction : executableActionList) { executor.execute(() -> { try { - String prompt = buildPrompt(actionData, data.getInput(), data.getRecentMessages()); + String prompt = buildPrompt(executableAction, data.getInput(), data.getRecentMessages()); ChatResponse response = this.singleChat(prompt); JSONObject tempResult = JSONObject.parseObject(extractJson(response.getMessage())); if (tempResult.getBoolean("confirmed")) { - actionData.setStatus(ActionData.ActionStatus.PREPARE); + executableAction.setStatus(ExecutableAction.Status.PREPARE); synchronized (uuids) { - uuids.add(actionData.getUuid()); + uuids.add(executableAction.getUuid()); } } } finally { @@ -62,7 +62,7 @@ public class ActionConfirmer extends AgentRunningSubModule recentMessages) { + private String buildPrompt(ExecutableAction data, String input, List recentMessages) { JSONObject prompt = new JSONObject(); prompt.put("[用户输入]", input); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java index 40b0b5ac..ae3d3dfb 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/confirmer/entity/ConfirmerInput.java @@ -2,13 +2,13 @@ package work.slhaf.partner.module.modules.action.planner.confirmer.entity; import lombok.Data; import work.slhaf.partner.api.chat.pojo.Message; -import work.slhaf.partner.core.action.entity.ActionData; +import work.slhaf.partner.core.action.entity.ExecutableAction; import java.util.List; @Data public class ConfirmerInput { private String input; - private List actionData; + private List executableActionData; private List recentMessages; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java index f6cf7c01..4b52edc0 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/planner/evaluator/entity/EvaluatorResult.java @@ -1,7 +1,7 @@ package work.slhaf.partner.module.modules.action.planner.evaluator.entity; import lombok.Data; -import work.slhaf.partner.core.action.entity.ScheduledActionData; +import work.slhaf.partner.core.action.entity.ScheduledExecutableAction; import java.util.List; import java.util.Map; @@ -12,7 +12,7 @@ public class EvaluatorResult { private boolean needConfirm; private ActionType type; private String scheduleContent; - private ScheduledActionData.ScheduleType scheduleType; + private ScheduledExecutableAction.ScheduleType scheduleType; private Map> primaryActionChain; private String tendency; private String reason; diff --git a/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java index ee4cfe6b..f660f376 100644 --- a/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java +++ b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutorTest.java @@ -72,7 +72,7 @@ class ActionExecutorTest { void setUp() { lenient().when(cognationCapability.getChatMessages()).thenReturn(Collections.emptyList()); lenient().when(memoryCapability.getActivatedSlices(anyString())).thenReturn(Collections.emptyList()); - lenient().when(actionCapability.putPhaserRecord(any(Phaser.class), any(ActionData.class))) + lenient().when(actionCapability.putPhaserRecord(any(Phaser.class), any(ExecutableAction.class))) .thenAnswer(inv -> new PhaserRecord(inv.getArgument(0), inv.getArgument(1))); lenient().when(actionCapability.loadMetaActionInfo(anyString())).thenAnswer(inv -> { MetaActionInfo info = new MetaActionInfo(); @@ -92,7 +92,7 @@ class ActionExecutorTest { ExecutorService directExecutor = new DirectExecutorService(); stubExecutors(directExecutor, directExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(false)); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult extractorResult = new ExtractorResult(); @@ -109,7 +109,7 @@ class ActionExecutorTest { verify(runnerClient, times(1)).submit(any(MetaAction.class)); verify(actionCapability, times(1)).removePhaserRecord(any(Phaser.class)); - assertEquals(ActionData.ActionStatus.SUCCESS, actionData.getStatus()); + assertEquals(ExecutableAction.Status.SUCCESS, actionData.getStatus()); assertEquals(1, actionData.getHistory().get(0).size()); } @@ -119,14 +119,14 @@ class ActionExecutorTest { ExecutorService directExecutor = new DirectExecutorService(); stubExecutors(directExecutor, directExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(false)); - actionData.setStatus(ActionData.ActionStatus.EXECUTING); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(false)); + actionData.setStatus(ExecutableAction.Status.EXECUTING); ActionExecutorInput input = buildInput("u1", actionData); actionExecutor.init(); actionExecutor.execute(input); - verify(actionCapability, never()).putPhaserRecord(any(Phaser.class), any(ActionData.class)); + verify(actionCapability, never()).putPhaserRecord(any(Phaser.class), any(ExecutableAction.class)); verify(runnerClient, never()).submit(any(MetaAction.class)); } @@ -140,7 +140,7 @@ class ActionExecutorTest { Map> chain = new HashMap<>(); chain.put(0, List.of(buildMetaAction("a1", false))); chain.put(1, List.of(buildMetaAction("a2", false))); - ImmediateActionData actionData = buildActionData(chain); + ImmediateExecutableAction actionData = buildActionData(chain); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult extractorResult = new ExtractorResult(); @@ -159,7 +159,7 @@ class ActionExecutorTest { verify(runnerClient, timeout(5000).times(2)).submit(any(MetaAction.class)); verify(actionCorrector, timeout(5000).times(2)).execute(any()); assertEquals(2, actionData.getHistory().size()); - assertEquals(ActionData.ActionStatus.SUCCESS, actionData.getStatus()); + assertEquals(ExecutableAction.Status.SUCCESS, actionData.getStatus()); } // 场景5:B4.2。目的:验证 IO 行动使用虚拟线程池。 @@ -169,7 +169,7 @@ class ActionExecutorTest { ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); stubExecutors(platformExecutor, virtualExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(true)); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(true)); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult extractorResult = new ExtractorResult(); @@ -195,7 +195,7 @@ class ActionExecutorTest { ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); stubExecutors(platformExecutor, virtualExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(false)); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult fail = new ExtractorResult(); @@ -233,7 +233,7 @@ class ActionExecutorTest { ExecutorService virtualExecutor = Executors.newVirtualThreadPerTaskExecutor(); stubExecutors(platformExecutor, virtualExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(false)); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult fail = new ExtractorResult(); @@ -264,7 +264,7 @@ class ActionExecutorTest { ExecutorService virtualExecutor = Executors.newCachedThreadPool(); stubExecutors(platformExecutor, virtualExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(false)); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult fail = new ExtractorResult(); @@ -291,13 +291,13 @@ class ActionExecutorTest { ExecutorService resumeExecutor = Executors.newSingleThreadExecutor(); resumeExecutor.execute(() -> { - while (actionData.getStatus() != ActionData.ActionStatus.INTERRUPTED) { + while (actionData.getStatus() != ExecutableAction.Status.INTERRUPTED) { try { Thread.sleep(10); } catch (InterruptedException ignored) { } } - actionData.setStatus(ActionData.ActionStatus.EXECUTING); + actionData.setStatus(ExecutableAction.Status.EXECUTING); }); actionExecutor.init(); @@ -318,7 +318,7 @@ class ActionExecutorTest { ExecutorService virtualExecutor = Executors.newCachedThreadPool(); stubExecutors(platformExecutor, virtualExecutor); - ImmediateActionData actionData = buildActionData(singleStageChain(false)); + ImmediateExecutableAction actionData = buildActionData(singleStageChain(false)); ActionExecutorInput input = buildInput("u1", actionData); ExtractorResult ok = new ExtractorResult(); @@ -351,7 +351,7 @@ class ActionExecutorTest { ExecutorService virtualExecutor = Executors.newCachedThreadPool(); stubExecutors(platformExecutor, virtualExecutor); - ImmediateActionData actionData = buildActionData(new HashMap<>()); + ImmediateExecutableAction actionData = buildActionData(new HashMap<>()); ActionExecutorInput input = buildInput("u1", actionData); actionExecutor.init(); @@ -369,12 +369,12 @@ class ActionExecutorTest { when(actionCapability.runnerClient()).thenReturn(runnerClient); } - private ActionExecutorInput buildInput(String userId, ImmediateActionData actionData) { + private ActionExecutorInput buildInput(String userId, ImmediateExecutableAction actionData) { return new ActionExecutorInput(Set.of(actionData)); } - private ImmediateActionData buildActionData(Map> actionChain) { - val immediateActionData = new ImmediateActionData( + private ImmediateExecutableAction buildActionData(Map> actionChain) { + val immediateActionData = new ImmediateExecutableAction( "tendency", actionChain, "reason", diff --git a/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt index 24d9c88c..8e6cf93f 100644 --- a/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt +++ b/Partner-Main/src/test/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionSchedulerTest.kt @@ -14,8 +14,9 @@ import org.mockito.Mockito.verify import org.mockito.junit.jupiter.MockitoExtension import org.slf4j.LoggerFactory import work.slhaf.partner.core.action.ActionCapability -import work.slhaf.partner.core.action.entity.ActionData -import work.slhaf.partner.core.action.entity.ScheduledActionData +import work.slhaf.partner.core.action.entity.ExecutableAction +import work.slhaf.partner.core.action.entity.Scheduled +import work.slhaf.partner.core.action.entity.ScheduledExecutableAction import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput import work.slhaf.partner.module.modules.action.dispatcher.scheduler.ActionScheduler import java.time.ZonedDateTime @@ -60,14 +61,14 @@ class ActionSchedulerTest { @Test fun `running test`() { - fun buildAction(time: ZonedDateTime): ScheduledActionData { - return ScheduledActionData( + fun buildAction(time: ZonedDateTime): ScheduledExecutableAction { + return ScheduledExecutableAction( "tendency", mutableMapOf(), "reason", "description", "source", - ScheduledActionData.ScheduleType.ONCE, + Scheduled.ScheduleType.ONCE, time.toString() ) } @@ -78,7 +79,7 @@ class ActionSchedulerTest { buildAction(now.truncatedTo(ChronoUnit.HOURS).plusHours(1).minusSeconds(1)), ) Mockito.`when`(actionCapability.listActions(null, null)) - .thenReturn(actions as Set) + .thenReturn(actions as Set) Mockito.`when`(actionExecutor.execute(any())) .thenAnswer { val input = it.arguments[0] as ActionExecutorInput @@ -107,7 +108,7 @@ class ActionSchedulerTest { val result = actionScheduler.execute(null) assertEquals(null, result) - verify(actionCapability, Mockito.never()).putAction(any(ActionData::class.java)) + verify(actionCapability, Mockito.never()).putAction(any(ExecutableAction::class.java)) } @Test @@ -115,7 +116,7 @@ class ActionSchedulerTest { // 场景编号:2;路径:B2 → B2.3;目的:验证正常入轮与副作用 initTimeWheelWithPrimaryActions(emptySet()) val action = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE, + type = Scheduled.ScheduleType.ONCE, ZonedDateTime.now().plusHours(1).toString() ) @@ -132,7 +133,7 @@ class ActionSchedulerTest { // 场景编号:3;路径:B2 → B2.1;目的:验证忽略非 PREPARE 状态 initTimeWheelWithPrimaryActions(emptySet()) val action = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE + type = Scheduled.ScheduleType.ONCE ) actionScheduler.execute(setOf(action)) @@ -147,7 +148,7 @@ class ActionSchedulerTest { // 场景编号:4;路径:B2 → B2.2;目的:验证解析失败被跳过 initTimeWheelWithPrimaryActions(emptySet()) val action = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE + type = Scheduled.ScheduleType.ONCE ) actionScheduler.execute(setOf(action)) @@ -161,7 +162,7 @@ class ActionSchedulerTest { // 场景编号:5;路径:B2 → B2.2;目的:验证 cron 解析失败被跳过 initTimeWheelWithPrimaryActions(emptySet()) val action = buildScheduledAction( - type = ScheduledActionData.ScheduleType.CYCLE, + type = Scheduled.ScheduleType.CYCLE, scheduleContentOverride = "invalid-cron" ) @@ -176,7 +177,7 @@ class ActionSchedulerTest { // 场景编号:6;路径:B2 异常中断;目的:验证异常传播 initTimeWheelWithPrimaryActions(emptySet()) val action = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE + type = Scheduled.ScheduleType.ONCE ) Mockito.doThrow(RuntimeException("boom")) .`when`(actionCapability) @@ -192,7 +193,7 @@ class ActionSchedulerTest { // 场景编号:7;路径:B2.3;目的:验证同小时调度触发 ACTIVE initTimeWheelWithPrimaryActions(emptySet()) val action = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE, + type = Scheduled.ScheduleType.ONCE, scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString() ) @@ -211,16 +212,16 @@ class ActionSchedulerTest { // 场景编号:15;路径:B2 + B2.1/B2.2/B2.3;目的:验证混合输入行为 initTimeWheelWithPrimaryActions(emptySet()) val ok = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE, + type = Scheduled.ScheduleType.ONCE, scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString() ) val nonPrepare = buildScheduledAction( - type = ScheduledActionData.ScheduleType.ONCE, + type = Scheduled.ScheduleType.ONCE, scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString() ) - nonPrepare.status = ActionData.ActionStatus.FAILED + nonPrepare.status = ExecutableAction.Status.FAILED val invalid = buildScheduledAction( - type = ScheduledActionData.ScheduleType.CYCLE, + type = Scheduled.ScheduleType.CYCLE, scheduleContentOverride = "invalid-cron" ) @@ -235,18 +236,18 @@ class ActionSchedulerTest { assertFalse(allScheduled.contains(invalid)) } - private fun initTimeWheelWithPrimaryActions(actions: Set) { + private fun initTimeWheelWithPrimaryActions(actions: Set) { @Suppress("UNCHECKED_CAST") Mockito.`when`(actionCapability.listActions(null, null)) - .thenReturn(actions as Set) + .thenReturn(actions as Set) actionScheduler.init() } private fun buildScheduledAction( - type: ScheduledActionData.ScheduleType, + type: Scheduled.ScheduleType, scheduleContentOverride: String? = null - ): ScheduledActionData { - val action = ScheduledActionData( + ): ScheduledExecutableAction { + val action = ScheduledExecutableAction( "test", mutableMapOf(), "reason", @@ -258,7 +259,7 @@ class ActionSchedulerTest { return action } - private fun ScheduledActionData.scheduleContentHour(): Int { + private fun ScheduledExecutableAction.scheduleContentHour(): Int { return ZonedDateTime.parse(this.scheduleContent).hour } @@ -269,14 +270,14 @@ class ActionSchedulerTest { } @Suppress("UNCHECKED_CAST") - private fun actionsGroupByHour(timeWheel: Any): Array> { + private fun actionsGroupByHour(timeWheel: Any): Array> { val field = timeWheel.javaClass.getDeclaredField("actionsGroupByHour") field.isAccessible = true - return field.get(timeWheel) as Array> + return field.get(timeWheel) as Array> } - private fun allScheduledActions(timeWheel: Any): Set { - val result = linkedSetOf() + private fun allScheduledActions(timeWheel: Any): Set { + val result = linkedSetOf() for (bucket in actionsGroupByHour(timeWheel)) { result.addAll(bucket) }