refactor(ActionCore): replace prepared action APIs with generic list/put

This commit is contained in:
2026-02-06 21:38:54 +08:00
parent 2cd0774834
commit 08100aea8a
5 changed files with 34 additions and 38 deletions

View File

@@ -1,6 +1,7 @@
package work.slhaf.partner.core.action; package work.slhaf.partner.core.action;
import lombok.NonNull; import lombok.NonNull;
import org.jetbrains.annotations.Nullable;
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.action.entity.ActionData; import work.slhaf.partner.core.action.entity.ActionData;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
@@ -12,17 +13,19 @@ import work.slhaf.partner.module.modules.action.interventor.entity.MetaIntervent
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
@Capability(value = "action") @Capability(value = "action")
public interface ActionCapability { public interface ActionCapability {
void putPreparedAction(String uuid, ActionData actionData);
void putAction(@NonNull ActionData actionData);
Set<ActionData> listActions(@Nullable ActionData.ActionStatus actionStatus, @Nullable String source);
List<ActionData> popPendingAction(String userId); List<ActionData> popPendingAction(String userId);
List<ActionData> listPreparedAction(String userId);
List<ActionData> listPendingAction(String userId); List<ActionData> listPendingAction(String userId);
void putPendingActions(String userId, ActionData actionData); void putPendingActions(String userId, ActionData actionData);
@@ -52,4 +55,5 @@ public interface ActionCapability {
RunnerClient runnerClient(); RunnerClient runnerClient();
void handleInterventions(List<MetaIntervention> interventions, ActionData data); void handleInterventions(List<MetaIntervention> interventions, ActionData data);
} }

View File

@@ -2,6 +2,8 @@ package work.slhaf.partner.core.action;
import lombok.NonNull; import lombok.NonNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.jetbrains.annotations.Nullable;
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.common.vector.VectorClient; import work.slhaf.partner.common.vector.VectorClient;
@@ -30,9 +32,9 @@ import java.util.stream.Collectors;
public class ActionCore extends PartnerCore<ActionCore> { public class ActionCore extends PartnerCore<ActionCore> {
/** /**
* 持久行动池以用户id为键存储所有状态的任务 * 持久行动池
*/ */
private HashMap<String, List<ActionData>> actionPool = new HashMap<>();// TODO 考虑是否取消用户分池 private CopyOnWriteArraySet<ActionData> actionPool = new CopyOnWriteArraySet<>();
/** /**
* 待确认任务以userId区分不同用户因为需要跨请求确认 * 待确认任务以userId区分不同用户因为需要跨请求确认
@@ -66,18 +68,24 @@ public class ActionCore extends PartnerCore<ActionCore> {
private void setupShutdownHook() { private void setupShutdownHook() {
// 将执行中的行动状态置为失败 // 将执行中的行动状态置为失败
List<ActionData> executingActionList = listExecutingAction(); val executingActionSet = listActions(ActionData.ActionStatus.EXECUTING, null);
for (ActionData actionData : executingActionList) { for (ActionData actionData : executingActionSet) {
actionData.setStatus(ActionData.ActionStatus.FAILED); actionData.setStatus(ActionData.ActionStatus.FAILED);
actionData.setResult("由于系统中断而失败"); actionData.setResult("由于系统中断而失败");
} }
} }
private List<ActionData> listExecutingAction() { @CapabilityMethod
return actionPool.values().stream() public void putAction(@NonNull ActionData actionData) {
.flatMap(Collection::stream) actionPool.add(actionData);
.filter(action -> action.getStatus() == ActionData.ActionStatus.EXECUTING) }
.collect(Collectors.toList());
@CapabilityMethod
public Set<ActionData> listActions(@Nullable ActionData.ActionStatus actionStatus, @Nullable String source) {
return actionPool.stream()
.filter(actionData -> actionStatus == null || actionData.getStatus().equals(actionStatus))
.filter(actionData -> source == null || actionData.getSource().equals(source))
.collect(Collectors.toSet());
} }
@CapabilityMethod @CapabilityMethod
@@ -96,23 +104,6 @@ public class ActionCore extends PartnerCore<ActionCore> {
return infos; return infos;
} }
@CapabilityMethod
public synchronized void putPreparedAction(String uuid, ActionData actionData) {
actionPool.computeIfAbsent(uuid, k -> {
List<ActionData> temp = new ArrayList<>();
temp.add(actionData);
return temp;
});
}
@CapabilityMethod
public List<ActionData> listPreparedAction(String userId) {
List<ActionData> actions = actionPool.get(userId);
return actions.stream()
.filter(actionData -> actionData.getStatus().equals(ActionData.ActionStatus.PREPARE))
.toList();
}
@CapabilityMethod @CapabilityMethod
public List<ActionData> listPendingAction(String userId) { public List<ActionData> listPendingAction(String userId) {
return pendingActions.get(userId); return pendingActions.get(userId);

View File

@@ -1,5 +1,6 @@
package work.slhaf.partner.module.modules.action.dispatcher; package work.slhaf.partner.module.modules.action.dispatcher;
import lombok.val;
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.api.agent.factory.module.annotation.Init;
@@ -46,7 +47,7 @@ public class ActionDispatcher extends PostRunningModule {
// action理想做法是将执行工具做成执行链的形式模型的自对话流程、是否通知用户都做成与普通工具同等的通用可选能力避免绑定固定流程 // action理想做法是将执行工具做成执行链的形式模型的自对话流程、是否通知用户都做成与普通工具同等的通用可选能力避免绑定固定流程
executor.execute(() -> { executor.execute(() -> {
String userId = context.getUserId(); String userId = context.getUserId();
List<ActionData> preparedActions = actionCapability.listPreparedAction(userId); val preparedActions = actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId);
// 分类成PLANNING和IMMEDIATE两类 // 分类成PLANNING和IMMEDIATE两类
List<ScheduledActionData> scheduledActions = new ArrayList<>(); List<ScheduledActionData> scheduledActions = new ArrayList<>();
List<ImmediateActionData> immediateActions = new ArrayList<>(); List<ImmediateActionData> immediateActions = new ArrayList<>();

View File

@@ -176,7 +176,7 @@ public class ActionInterventor extends PreRunningModule implements ActivateModel
// 参考的对话列表大小或需调整 // 参考的对话列表大小或需调整
recognizerInput.setRecentMessages(cognationCapability.getChatMessages()); recognizerInput.setRecentMessages(cognationCapability.getChatMessages());
recognizerInput.setExecutingActions(actionCapability.listPhaserRecords().stream().map(PhaserRecord::actionData).toList()); recognizerInput.setExecutingActions(actionCapability.listPhaserRecords().stream().map(PhaserRecord::actionData).toList());
recognizerInput.setPreparedActions(actionCapability.listPreparedAction(userId)); recognizerInput.setPreparedActions(actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId).stream().toList());
return recognizerInput; return recognizerInput;
} }

View File

@@ -1,6 +1,7 @@
package work.slhaf.partner.module.modules.action.planner; package work.slhaf.partner.module.modules.action.planner;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
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;
@@ -142,11 +143,10 @@ public class ActionPlanner extends PreRunningModule {
if (uuids == null) { if (uuids == null) {
return; return;
} }
String contextUuid = context.getUuid();
List<ActionData> pendingActions = actionCapability.popPendingAction(context.getUserId()); List<ActionData> pendingActions = actionCapability.popPendingAction(context.getUserId());
for (ActionData actionData : pendingActions) { for (ActionData actionData : pendingActions) {
if (uuids.contains(actionData.getUuid())) { if (uuids.contains(actionData.getUuid())) {
actionCapability.putPreparedAction(contextUuid, actionData); actionCapability.putAction(actionData);
} }
} }
} }
@@ -157,7 +157,7 @@ public class ActionPlanner extends PreRunningModule {
if (evaluatorResult.isNeedConfirm()) { if (evaluatorResult.isNeedConfirm()) {
actionCapability.putPendingActions(context.getUserId(), actionData); actionCapability.putPendingActions(context.getUserId(), actionData);
} else { } else {
actionCapability.putPreparedAction(context.getUuid(), actionData); actionCapability.putAction(actionData);
} }
} }
} }
@@ -183,13 +183,13 @@ public class ActionPlanner extends PreRunningModule {
} }
private void setupPreparedActions(HashMap<String, String> map, String userId) { private void setupPreparedActions(HashMap<String, String> map, String userId) {
List<ActionData> actionData = actionCapability.listPreparedAction(userId); val preparedActions = actionCapability.listActions(ActionData.ActionStatus.PREPARE, userId).stream().toList();
if (actionData == null || actionData.isEmpty()) { if (preparedActions.isEmpty()) {
map.put("[预备行动] <预备执行或放入计划池的行动信息>", "无预备行动"); map.put("[预备行动] <预备执行或放入计划池的行动信息>", "无预备行动");
return; return;
} }
for (int i = 0; i < actionData.size(); i++) { for (int i = 0; i < preparedActions.size(); i++) {
map.put("[预备行动 " + (i + 1) + " ] <预备执行或放入计划池的行动信息>", generateActionStr(actionData.get(i))); map.put("[预备行动 " + (i + 1) + " ] <预备执行或放入计划池的行动信息>", generateActionStr(preparedActions.get(i)));
} }
} }