mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
fix(action): correct action chain fixing error
This commit is contained in:
@@ -399,6 +399,9 @@ public class ActionPlanner extends AbstractAgentModule.Running<PartnerRunningFlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean fixDependencies(Map<Integer, List<String>> primaryActionChain) {
|
private boolean fixDependencies(Map<Integer, List<String>> primaryActionChain) {
|
||||||
|
if (primaryActionChain == null || primaryActionChain.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// 先将 primaryActionChain 的节点序号修正为从1开始依次增大
|
// 先将 primaryActionChain 的节点序号修正为从1开始依次增大
|
||||||
fixOrder(primaryActionChain);
|
fixOrder(primaryActionChain);
|
||||||
List<Integer> fixedOrders = new ArrayList<>(primaryActionChain.keySet().stream().toList());
|
List<Integer> fixedOrders = new ArrayList<>(primaryActionChain.keySet().stream().toList());
|
||||||
@@ -409,6 +412,9 @@ public class ActionPlanner extends AbstractAgentModule.Running<PartnerRunningFlo
|
|||||||
for (Integer fixedOrder : fixedOrders) {
|
for (Integer fixedOrder : fixedOrders) {
|
||||||
int lastOrder = fixedOrder - 1;
|
int lastOrder = fixedOrder - 1;
|
||||||
List<String> actionKeys = primaryActionChain.get(fixedOrder);
|
List<String> actionKeys = primaryActionChain.get(fixedOrder);
|
||||||
|
if (actionKeys == null || actionKeys.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (String actionKey : actionKeys) {
|
for (String actionKey : actionKeys) {
|
||||||
// 根据 actionKey 加载行动信息,并检查是否存在必需前置依赖
|
// 根据 actionKey 加载行动信息,并检查是否存在必需前置依赖
|
||||||
|
|
||||||
@@ -451,9 +457,12 @@ public class ActionPlanner extends AbstractAgentModule.Running<PartnerRunningFlo
|
|||||||
private void fixOrder(Map<Integer, List<String>> primaryActionChain) {
|
private void fixOrder(Map<Integer, List<String>> primaryActionChain) {
|
||||||
Map<Integer, List<String>> tempChain = new HashMap<>(primaryActionChain);
|
Map<Integer, List<String>> tempChain = new HashMap<>(primaryActionChain);
|
||||||
primaryActionChain.clear();
|
primaryActionChain.clear();
|
||||||
int chainSize = tempChain.size();
|
List<Integer> orders = new ArrayList<>(tempChain.keySet());
|
||||||
for (int i = 0; i < chainSize; i++) {
|
orders.sort(Integer::compareTo);
|
||||||
primaryActionChain.put(i, tempChain.get(i));
|
int fixedOrder = 1;
|
||||||
|
for (Integer order : orders) {
|
||||||
|
List<String> actionKeys = tempChain.get(order);
|
||||||
|
primaryActionChain.put(fixedOrder++, actionKeys == null ? new ArrayList<>() : new ArrayList<>(actionKeys));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package work.slhaf.partner.module.action.planner.evaluator.entity;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import work.slhaf.partner.core.action.entity.Schedulable;
|
import work.slhaf.partner.core.action.entity.Schedulable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -31,9 +32,15 @@ public class EvaluatorResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, List<String>> getPrimaryActionChainAsMap() {
|
public Map<Integer, List<String>> getPrimaryActionChainAsMap() {
|
||||||
|
if (primaryActionChain == null || primaryActionChain.isEmpty()) {
|
||||||
|
return new LinkedHashMap<>();
|
||||||
|
}
|
||||||
return primaryActionChain.stream().collect(Collectors.toMap(
|
return primaryActionChain.stream().collect(Collectors.toMap(
|
||||||
ChainElement::getOrder,
|
ChainElement::getOrder,
|
||||||
ChainElement::getActionKeys,
|
chainElement -> {
|
||||||
|
List<String> actionKeys = chainElement.getActionKeys();
|
||||||
|
return actionKeys == null ? new ArrayList<>() : new ArrayList<>(actionKeys);
|
||||||
|
},
|
||||||
(oldValue, newValue) -> newValue,
|
(oldValue, newValue) -> newValue,
|
||||||
LinkedHashMap::new
|
LinkedHashMap::new
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package work.slhaf.partner.module.action.planner;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import work.slhaf.partner.core.action.ActionCapability;
|
||||||
|
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||||
|
import work.slhaf.partner.framework.agent.support.Result;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class ActionPlannerAssemblyHelperTest {
|
||||||
|
|
||||||
|
private static void injectField(Object target, String fieldName, Object value) throws Exception {
|
||||||
|
Field field = target.getClass().getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(target, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object getField(Object target, String fieldName) throws Exception {
|
||||||
|
Field field = target.getClass().getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldFixNonZeroBasedOrdersWithoutInjectingNullActionKeyList() throws Exception {
|
||||||
|
ActionCapability actionCapability = Mockito.mock(ActionCapability.class);
|
||||||
|
Mockito.when(actionCapability.loadMetaActionInfo(Mockito.anyString()))
|
||||||
|
.thenReturn(Result.success(new MetaActionInfo(
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
Map.of(),
|
||||||
|
"desc",
|
||||||
|
Set.of(),
|
||||||
|
Set.of(),
|
||||||
|
Set.of(),
|
||||||
|
false,
|
||||||
|
new JSONObject()
|
||||||
|
)));
|
||||||
|
|
||||||
|
ActionPlanner planner = new ActionPlanner();
|
||||||
|
injectField(planner, "actionCapability", actionCapability);
|
||||||
|
|
||||||
|
Object helper = getField(planner, "assemblyHelper");
|
||||||
|
Method fixDependencies = helper.getClass().getDeclaredMethod("fixDependencies", Map.class);
|
||||||
|
fixDependencies.setAccessible(true);
|
||||||
|
|
||||||
|
Map<Integer, List<String>> chain = new LinkedHashMap<>();
|
||||||
|
chain.put(1, new ArrayList<>(List.of("action_a")));
|
||||||
|
chain.put(2, new ArrayList<>(List.of("action_b")));
|
||||||
|
|
||||||
|
boolean fixed = (boolean) fixDependencies.invoke(helper, chain);
|
||||||
|
|
||||||
|
assertTrue(fixed);
|
||||||
|
assertEquals(List.of(1, 2), new ArrayList<>(chain.keySet()));
|
||||||
|
assertEquals(List.of("action_a"), chain.get(1));
|
||||||
|
assertEquals(List.of("action_b"), chain.get(2));
|
||||||
|
assertFalse(chain.containsValue(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package work.slhaf.partner.module.action.planner.evaluator.entity;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class EvaluatorResultTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnEmptyMapWhenPrimaryActionChainIsNull() {
|
||||||
|
EvaluatorResult result = new EvaluatorResult();
|
||||||
|
Map<Integer, List<String>> chain = result.getPrimaryActionChainAsMap();
|
||||||
|
assertNotNull(chain);
|
||||||
|
assertTrue(chain.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldNormalizeNullActionKeysToEmptyList() {
|
||||||
|
EvaluatorResult result = new EvaluatorResult();
|
||||||
|
EvaluatorResult.ChainElement element = new EvaluatorResult.ChainElement();
|
||||||
|
element.setOrder(1);
|
||||||
|
element.setActionKeys(null);
|
||||||
|
result.setPrimaryActionChain(List.of(element));
|
||||||
|
|
||||||
|
Map<Integer, List<String>> chain = result.getPrimaryActionChainAsMap();
|
||||||
|
assertEquals(1, chain.size());
|
||||||
|
assertNotNull(chain.get(1));
|
||||||
|
assertTrue(chain.get(1).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldCopyActionKeyListDefensively() {
|
||||||
|
EvaluatorResult result = new EvaluatorResult();
|
||||||
|
EvaluatorResult.ChainElement element = new EvaluatorResult.ChainElement();
|
||||||
|
element.setOrder(1);
|
||||||
|
List<String> keys = new ArrayList<>(List.of("a"));
|
||||||
|
element.setActionKeys(keys);
|
||||||
|
result.setPrimaryActionChain(List.of(element));
|
||||||
|
|
||||||
|
Map<Integer, List<String>> chain = result.getPrimaryActionChainAsMap();
|
||||||
|
keys.add("b");
|
||||||
|
|
||||||
|
assertEquals(new LinkedHashMap<>(Map.of(1, List.of("a"))), new LinkedHashMap<>(chain));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user