From 503afecbe275332009961f32b947621bc5f90cce Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Thu, 16 Apr 2026 23:27:46 +0800 Subject: [PATCH] refactor(action): redefine ExtractorResult structure to support openai sdk better, and make failed meta-action executing should be recorded as history normally --- .idea/dictionaries/project.xml | 1 + .../action/builtin/BuiltinActionRegistry.java | 12 +++++ .../action/executor/ActionExecutor.java | 49 +++++++++++++++---- .../executor/ExecutingActionBlockManager.java | 11 +++-- .../action/executor/ParamsExtractor.java | 6 +-- .../executor/entity/ExtractorResult.java | 12 ++++- .../action/executor/ActionExecutorTest.java | 15 +++++- 7 files changed, 86 insertions(+), 20 deletions(-) diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index e3f440ad..3833463d 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -1,6 +1,7 @@ + openai zuper diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/builtin/BuiltinActionRegistry.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/builtin/BuiltinActionRegistry.java index 6ad60cb9..da5b07de 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/builtin/BuiltinActionRegistry.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/builtin/BuiltinActionRegistry.java @@ -112,6 +112,12 @@ public class BuiltinActionRegistry extends AbstractAgentModule.Standalone { if (value instanceof Number number) { return number.intValue(); } + try { + if (value instanceof String string) { + return Integer.parseInt(string); + } + } catch (NumberFormatException ignored) { + } throw new IllegalArgumentException("参数 " + key + " 必须为整数"); } @@ -123,6 +129,12 @@ public class BuiltinActionRegistry extends AbstractAgentModule.Standalone { if (value instanceof Number n) { return n.intValue(); } + try { + if (value instanceof String string) { + return Integer.parseInt(string); + } + } catch (NumberFormatException ignored) { + } throw new IllegalArgumentException("参数 " + key + " 必须为整数"); } diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java index c15fad1e..04796432 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java @@ -304,13 +304,13 @@ public class ActionExecutor extends AbstractAgentModule.Standalone { private void executeMetaActionWithRetry(MetaAction metaAction, ExecutableAction actionData) { AtomicReference failureReason = new AtomicReference<>("参数提取失败"); val actionKey = metaAction.getKey(); + int executingStage = actionData.getExecutingStage(); + boolean succeeded = false; for (int attempt = 1; attempt <= MAX_EXTRACTOR_ATTEMPTS; attempt++) { val result = metaAction.getResult(); result.reset(); metaAction.getParams().clear(); - val executingStage = actionData.getExecutingStage(); - Result extractorInputResult = assemblyHelper.buildExtractorInput(metaAction.getKey(), actionData.getUuid(), actionData.getDescription()); AgentRuntimeException exception = extractorInputResult.exceptionOrNull(); if (exception != null) { @@ -331,7 +331,7 @@ public class ActionExecutor extends AbstractAgentModule.Standalone { failureReason.set(buildAttemptFailureReason("参数提取失败", null)); continue; } - metaAction.getParams().putAll(extractorResult.getParams()); + metaAction.getParams().putAll(toMetaActionParams(extractorResult.getParams())); try { runnerClient.submit(metaAction); @@ -341,17 +341,46 @@ public class ActionExecutor extends AbstractAgentModule.Standalone { } if (result.getStatus() == MetaAction.Result.Status.SUCCESS) { - val historyAction = new HistoryAction(actionKey, resolveHistoryDescription(actionKey), result.getData()); - actionData.getHistory() - .computeIfAbsent(executingStage, integer -> new ArrayList<>()) - .add(historyAction); - return; + succeeded = true; + break; } failureReason.set(buildAttemptFailureReason("行动执行失败", result.getData())); } - metaAction.getResult().setStatus(MetaAction.Result.Status.FAILED); - metaAction.getResult().setData(failureReason.get()); + if (!succeeded) { + metaAction.getResult().setStatus(MetaAction.Result.Status.FAILED); + metaAction.getResult().setData(failureReason.get()); + } + appendHistoryAction(actionData, executingStage, metaAction); + } + + private Map toMetaActionParams(List params) { + if (params == null || params.isEmpty()) { + return Map.of(); + } + Map converted = new LinkedHashMap<>(); + for (ExtractorResult.ParamEntry entry : params) { + if (entry == null) { + continue; + } + String name = entry.getName(); + if (name == null || name.isBlank()) { + continue; + } + converted.put(name, entry.getValue()); + } + return converted; + } + + private void appendHistoryAction(ExecutableAction actionData, int executingStage, MetaAction metaAction) { + HistoryAction historyAction = new HistoryAction( + metaAction.getKey(), + resolveHistoryDescription(metaAction.getKey()), + metaAction.getResult().getData() + ); + actionData.getHistory() + .computeIfAbsent(executingStage, integer -> new ArrayList<>()) + .add(historyAction); } private RecognizerTaskRecord startRecognizerIfNeeded(ExecutableAction executableAction, Phaser phaser) { diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java index 2d46d4fd..bdbc5d36 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java @@ -239,7 +239,7 @@ class ExecutingActionBlockManager { private @NotNull BlockContent buildActionStageAbstractBlock(ExecutableActionSnapshot snapshot, String blockName, String event) { int settledStage = snapshot.getExecutingStage(); - List history = snapshot.getHistory().get(settledStage); + List history = resolveStageHistory(snapshot, settledStage); return new ActionBlockContent(blockName, SOURCE) { @Override @@ -252,7 +252,7 @@ class ExecutingActionBlockManager { private @NotNull BlockContent buildActionStageCompactBlock(ExecutableActionSnapshot snapshot, String blockName, String emittedAt, String event) { int settledStage = snapshot.getExecutingStage(); - List history = snapshot.getHistory().get(settledStage); + List history = resolveStageHistory(snapshot, settledStage); return new ActionBlockContent(blockName, SOURCE) { @Override @@ -267,7 +267,7 @@ class ExecutingActionBlockManager { private @NotNull BlockContent buildActionStageFullBlock(ExecutableActionSnapshot snapshot, String blockName, String emittedAt, String event) { int settledStage = snapshot.getExecutingStage(); - List history = snapshot.getHistory().get(settledStage); + List history = resolveStageHistory(snapshot, settledStage); return new ActionBlockContent(blockName, SOURCE) { @Override @@ -312,6 +312,11 @@ class ExecutingActionBlockManager { )); } + private List resolveStageHistory(ExecutableActionSnapshot snapshot, int settledStage) { + List history = snapshot.getHistory().get(settledStage); + return history == null ? List.of() : history; + } + private @NotNull BlockContent buildActionCorrectionAbstractBlock(ExecutableActionSnapshot snapshot, List interventions, String blockName, String event) { return new ActionBlockContent(blockName, SOURCE) { @Override diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ParamsExtractor.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ParamsExtractor.java index 3f2c2e3b..5b4c766e 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ParamsExtractor.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ParamsExtractor.java @@ -39,9 +39,9 @@ public class ParamsExtractor extends AbstractAgentModule.Sub { - appendTextElement(document, blok, "uuid", input.getTargetActionId()); - appendTextElement(document, blok, "description", input.getTargetActionDesc()); + appendChildElement(document, root, "target_action", block -> { + appendTextElement(document, block, "uuid", input.getTargetActionId()); + appendTextElement(document, block, "description", input.getTargetActionDesc()); return Unit.INSTANCE; }); appendChildElement(document, root, "meta_action_info", element -> { diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/entity/ExtractorResult.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/entity/ExtractorResult.java index cfeb74c4..93fd854b 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/entity/ExtractorResult.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/entity/ExtractorResult.java @@ -1,11 +1,19 @@ package work.slhaf.partner.module.action.executor.entity; +import lombok.AllArgsConstructor; import lombok.Data; -import java.util.Map; +import java.util.List; @Data public class ExtractorResult { private boolean ok; - private Map params; + private List params; + + @Data + @AllArgsConstructor + public static class ParamEntry { + private String name; + private String value; + } } diff --git a/Partner-Core/src/test/java/work/slhaf/partner/module/action/executor/ActionExecutorTest.java b/Partner-Core/src/test/java/work/slhaf/partner/module/action/executor/ActionExecutorTest.java index 2ee8576a..5a5a668a 100644 --- a/Partner-Core/src/test/java/work/slhaf/partner/module/action/executor/ActionExecutorTest.java +++ b/Partner-Core/src/test/java/work/slhaf/partner/module/action/executor/ActionExecutorTest.java @@ -1,7 +1,9 @@ package work.slhaf.partner.module.action.executor; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.mockito.Mockito; import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; @@ -14,6 +16,7 @@ import work.slhaf.partner.module.action.executor.entity.ExtractorResult; import work.slhaf.partner.module.action.executor.entity.HistoryAction; import java.lang.reflect.Field; +import java.nio.file.Path; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -29,6 +32,11 @@ class ActionExecutorTest { private final List executors = new ArrayList<>(); + @BeforeAll + static void beforeAll(@TempDir Path tempDir) { + System.setProperty("user.home", tempDir.toAbsolutePath().toString()); + } + private static void inject(Object target, String fieldName, Object value) throws Exception { Field field = ActionExecutor.class.getDeclaredField(fieldName); field.setAccessible(true); @@ -137,7 +145,7 @@ class ActionExecutorTest { ExtractorResult extractorResult = new ExtractorResult(); extractorResult.setOk(true); - extractorResult.setParams(Map.of("fresh", "value")); + extractorResult.setParams(List.of(new ExtractorResult.ParamEntry("fresh", "value"))); when(paramsExtractor.execute(any())).thenReturn(Result.success(extractorResult)); doAnswer(invocation -> { MetaAction metaAction = invocation.getArgument(0); @@ -242,6 +250,9 @@ class ActionExecutorTest { assertEquals(MetaAction.Result.Status.FAILED, metaAction.getResult().getStatus()); assertTrue(metaAction.getResult().getData().contains("missing")); assertEquals(metaAction.getResult().getData(), action.getResult()); + assertEquals(1, action.getHistory().size()); + assertTrue(action.getHistory().containsKey(1)); + assertEquals(metaAction.getResult().getData(), action.getHistory().get(1).getFirst().result()); } @Test @@ -282,7 +293,7 @@ class ActionExecutorTest { ExtractorResult extractorResult = new ExtractorResult(); extractorResult.setOk(true); - extractorResult.setParams(Map.of("fresh", "value")); + extractorResult.setParams(List.of(new ExtractorResult.ParamEntry("fresh", "value"))); when(paramsExtractor.execute(any())).thenReturn(Result.success(extractorResult)); doAnswer(invocation -> { MetaAction metaAction = invocation.getArgument(0);